質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
データ構造

データ構造とは、データの集まりをコンピュータの中で効果的に扱うために、一定の形式に系統立てて格納する形式を指します。(配列/連想配列/木構造など)

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Q&A

2回答

427閲覧

Dataframe.queryの結果がカラム名によって異なる

svg

総合スコア0

データ構造

データ構造とは、データの集まりをコンピュータの中で効果的に扱うために、一定の形式に系統立てて格納する形式を指します。(配列/連想配列/木構造など)

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

0グッド

1クリップ

投稿2023/01/21 09:53

前提

カラム名によって違いが生じる原因を調査しています。

顧客情報(customer_id)と売上日(sales_ymd)を持つ df_receipt というDataframeがあります。
sales_ymd が複数ある状況で、customer_id 毎に最新と最古の sales_ymd が異なるものを抽出したく考えています。

下記のように書いたものは正常に動作します。

df_tmp = df_receipt.groupby('customer_id').agg({'sales_ymd':['max','min']}).reset_index() df_tmp.columns = ['customer_id', 'sales_max', 'sales_min'] df_tmp.query('sales_max != sales_min')

一方で、カラム名をmax、minとした時、それぞれが同じものも返されてしまいます。(query部分が想定通り動いていません。)

df_tmp = df_receipt.groupby('customer_id').agg({'sales_ymd':['max','min']}).reset_index() df_tmp.columns = ['customer_id', 'max', 'min'] df_tmp.query('max != min')

カラム名が異なるだけなので予約後が関係しているかと思われるのですが、内部でどのように処理が行われているのか調べてもわからず、ご教示いただきたく考えております。
初歩的で恐縮ですが何卒よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

melian

2023/01/21 10:31

参考までに、適当にデータフレームを作成して Python 3.10.6/Pandas 1.5.3 で実行してみましたが、どちらも同じ結果になりました。
guest

回答2

0

試してみたところ、query の engine に python を使うか、numexpr を使うかで、動きが違っていますね。
(pandas 1.5.3, numexpr 2.8.4)
engine のデフォルトは、numexpr がインストールされている場合は numexpr を使って、インストールされていない場合は python になるはずです。

この例で、pandas と numexpr のそれぞれがどう動いているのか、ドキュメントを探ってもよくわかりませんでした。numexpr が max と min を変数(カラム名)としてではなく、予約された関数名として扱っていて max != min → True としていそうな気がします。
対処法としては、下記のようになるのかと思います。
①maxとかminとかのカラム名を使わない
②queryを使わない (booleanインデックスを使う)
③engine='python' にする (これで確実に大丈夫なのかは不明)

python

1import pandas as pd 2 3df = pd.DataFrame({ 4 'cid': ['a', 'b', 'c'], 5 'min': [1, 2, 3], 6 'max': [1, 3, 5], 7}) 8 9print(df.query('min != max', engine='numexpr')) 10# cid min max 11#0 a 1 1 12#1 b 2 3 13#2 c 3 5 14print(df.query('min != max', engine='python')) 15# cid min max 16#1 b 2 3 17#2 c 3 5

追記

numexpr の evaluate に local_dict で渡しても、max を変数としては扱ってくれませんでした。
なので、numexpr の予約語扱いになっているものは、うまく扱えないんじゃないでしょうか。
(何が予約語扱いなのかが不明ですが・・・)

python

1import numexpr as ne 2 3ne.evaluate('max', local_dict={'max': 1}) 4# TypeError: unsupported expression type: <class 'function'>

投稿2023/01/22 10:49

編集2023/01/22 12:01
bsdfan

総合スコア4567

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

動作未検証ですがPandas query function not working with spaces in column namesの回答のように列名をバッククオートで囲むことで、正しく列名として識別されて動作するかもしれません(しないかもしれません)

ただいずれにせよ、maxなどの予約語を列名とするのは可能であれば避けたほうがよいと思います。
参考:Alternatives to pandas.query() when the column name is a Python keyword (import, sum, min etc)?

投稿2023/01/22 03:12

can110

総合スコア38266

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問