web-dev-qa-db-ja.com

pandasデータフレームをサブセット化する最良の方法

Pandasが初めてですが、df.query()に遭遇しました。

ブラケット表記を使用してデータフレームを直接フィルタリングできるのに、なぜdf.query()を使用するのですか?公式のpandasチュートリアルも後者のアプローチを好むようです。

ブラケット表記あり:

df[df['age'] <= 21]

pandas query method:

df.query('age <= 21')

言及されているいくつかのスタイルまたは柔軟性の違いに加えて、1つは標準的に優先されます。

8

次のサンプルDFを考えてみます。

_In [307]: df
Out[307]:
  sex  age     name
0   M   40      Max
1   F   35     Anna
2   M   29      Joe
3   F   18    Maria
4   F   23  Natalie
_

.query()メソッドを選択するのにはかなりの理由があります。

  • ブールインデックスに比べて、はるかに短くてクリーンな場合があります。

    _In [308]: df.query("20 <= age <= 30 and sex=='F'")
    Out[308]:
      sex  age     name
    4   F   23  Natalie
    
    In [309]: df[(df['age']>=20) & (df['age']<=30) & (df['sex']=='F')]
    Out[309]:
      sex  age     name
    4   F   23  Natalie
    _
  • プログラムで条件(クエリ)を準備できます。

    _In [315]: conditions = {'name':'Joe', 'sex':'M'}
    
    In [316]: q = ' and '.join(['{}=="{}"'.format(k,v) for k,v in conditions.items()])
    
    In [317]: q
    Out[317]: 'name=="Joe" and sex=="M"'
    
    In [318]: df.query(q)
    Out[318]:
      sex  age name
    2   M   29  Joe
    _

PSにはいくつかの欠点もあります:

  • 数字のみで構成されるスペースまたは列を含む列には.query()メソッドを使用できません
  • すべての関数を適用できるわけではありません。または、デフォルトの_engine='python'_(より高速)ではなく_engine='numexpr'_を使用する必要がある場合もあります。

注:ジェフ(メインのPandas貢献者の1人であり、Pandasコアチーム)のメンバー) かつて

実際には.queryは単に使いやすいインターフェースであり、実際には非常に具体的な保証があります。つまり、完全に一般的なインターフェースではなく、クエリ言語のように解析することを意味します。

7
MaxU

ドキュメント でのその他の興味深い使用法。

再利用可能

Query()の使用例は、列名(またはインデックスレベル/名前)のサブセットが共通にあるDataFrameオブジェクトのコレクションがある場合ですクエリの対象となるフレームを指定せずに、同じクエリを両方のフレームに渡すことができます- (Source)

例:

dfA = pd.DataFrame([[1,2,3], [4,5,6]], columns=["X", "Y", "Z"])
dfB = pd.DataFrame([[1,3,3], [4,1,6]], columns=["X", "Y", "Z"])
q = "(X > 3) & (Y < 10)"

print(dfA.query(q))
print(dfB.query(q))

   X  Y  Z
1  4  5  6
   X  Y  Z
1  4  1  6

より柔軟な構文

df.query('a < b and b < c')  # understand a bit more English

in演算子とnot inisinの代替)をサポート

df.query('a in [3, 4, 5]') # select rows whose value of column a is in [2, 3, 4]

==および!=の特別な使用法(in/not inと同様)

df.query('a == [1, 3, 5]') # select whose value of column a is in [1, 3, 5]
# equivalent to df.query('a in [1, 3, 5]')
2
Tai