399

のほとんどの操作は、pandas演算子チェーン(、、、など)を使用して実行できますgroupbyが、行をフィルタリングする唯一の方法は、通常の角かっこインデックスを使用することです。aggregateapply

df_filtered = df[df['column'] == value]

df値をフィルタリングする前に変数に割り当てる必要があるため、これは魅力的ではありません。次のようなものはありますか?

df_filtered = df.mask(lambda x: x['column'] == value)
4

15 に答える 15

454

私はあなたが何を望んでいるか完全にはわかりません、そしてあなたのコードの最後の行も役に立ちませんが、とにかく:

「連鎖」フィルタリングは、ブールインデックスの基準を「連鎖」することによって行われます。

In [96]: df
Out[96]:
   A  B  C  D
a  1  4  9  1
b  4  5  0  2
c  5  5  1  0
d  1  3  9  6

In [99]: df[(df.A == 1) & (df.D == 6)]
Out[99]:
   A  B  C  D
d  1  3  9  6

メソッドをチェーンしたい場合は、独自のマスクメソッドを追加してそれを使用できます。

In [90]: def mask(df, key, value):
   ....:     return df[df[key] == value]
   ....:

In [92]: pandas.DataFrame.mask = mask

In [93]: df = pandas.DataFrame(np.random.randint(0, 10, (4,4)), index=list('abcd'), columns=list('ABCD'))

In [95]: df.ix['d','A'] = df.ix['a', 'A']

In [96]: df
Out[96]:
   A  B  C  D
a  1  4  9  1
b  4  5  0  2
c  5  5  1  0
d  1  3  9  6

In [97]: df.mask('A', 1)
Out[97]:
   A  B  C  D
a  1  4  9  1
d  1  3  9  6

In [98]: df.mask('A', 1).mask('D', 6)
Out[98]:
   A  B  C  D
d  1  3  9  6
于 2012-08-08T20:10:43.290 に答える
138

フィルタは、Pandasクエリを使用してチェーンできます。

df = pd.DataFrame(np.random.randn(30, 3), columns=['a','b','c'])
df_filtered = df.query('a > 0').query('0 < b < 2')

フィルタは、単一のクエリに組み合わせることもできます。

df_filtered = df.query('a > 0 and 0 < b < 2')
于 2015-01-26T21:44:19.280 に答える
76

@lodagroからの答えは素晴らしいです。マスク関数を次のように一般化することで拡張します。

def mask(df, f):
  return df[f(df)]

次に、次のようなことを行うことができます。

df.mask(lambda x: x[0] < 0).mask(lambda x: x[1] > 0)
于 2012-08-09T23:20:59.093 に答える
34

バージョン0.18.1以降、.locメソッドは選択のために呼び出し可能オブジェクトを受け入れます。ラムダ関数と一緒に、非常に柔軟なチェーン可能なフィルターを作成できます。

import numpy as np
import pandas as pd

df = pd.DataFrame(np.random.randint(0,100,size=(100, 4)), columns=list('ABCD'))
df.loc[lambda df: df.A == 80]  # equivalent to df[df.A == 80] but chainable

df.sort_values('A').loc[lambda df: df.A > 80].loc[lambda df: df.B > df.A]

フィルタリングだけを行っている場合は、を省略することもできます.loc

于 2017-09-05T10:14:25.817 に答える
21

pandasは、オーバーライドを必要としないWouterOvermeireの回答に代わる2つの選択肢を提供します。1つは.loc[.]、次のように呼び出し可能です。

df_filtered = df.loc[lambda x: x['column'] == value]

もう1つは.pipe()

df_filtered = df.pipe(lambda x: x.loc[x['column'] == value])
于 2018-03-22T14:44:14.537 に答える
19

追加の例としてこれを提供します。これはhttps://stackoverflow.com/a/28159296/と同じ答えです

この投稿をより便利にするために、他の編集を追加します。

pandas.DataFrame.query
queryまさにこの目的のために作られました。データフレームを検討するdf

import pandas as pd
import numpy as np

np.random.seed([3,1415])
df = pd.DataFrame(
    np.random.randint(10, size=(10, 5)),
    columns=list('ABCDE')
)

df

   A  B  C  D  E
0  0  2  7  3  8
1  7  0  6  8  6
2  0  2  0  4  9
3  7  3  2  4  3
4  3  6  7  7  4
5  5  3  7  5  9
6  8  7  6  4  7
7  6  2  6  6  5
8  2  8  7  5  8
9  4  7  6  1  5

queryを使用して、すべての行をフィルタリングしてみましょう。D > B

df.query('D > B')

   A  B  C  D  E
0  0  2  7  3  8
1  7  0  6  8  6
2  0  2  0  4  9
3  7  3  2  4  3
4  3  6  7  7  4
5  5  3  7  5  9
7  6  2  6  6  5

チェーンする

df.query('D > B').query('C > B')
# equivalent to
# df.query('D > B and C > B')
# but defeats the purpose of demonstrating chaining

   A  B  C  D  E
0  0  2  7  3  8
1  7  0  6  8  6
4  3  6  7  7  4
5  5  3  7  5  9
7  6  2  6  6  5
于 2017-06-04T04:40:30.143 に答える
10

基準をOR条件に結合したかったことを除いて、同じ質問がありました。Wouter Overmeireによって与えられた形式は、両方が満たされなければならないように、基準をAND条件に結合します。

In [96]: df
Out[96]:
   A  B  C  D
a  1  4  9  1
b  4  5  0  2
c  5  5  1  0
d  1  3  9  6

In [99]: df[(df.A == 1) & (df.D == 6)]
Out[99]:
   A  B  C  D
d  1  3  9  6

しかし、各条件をラップし(... == True)て基準をパイプで結合すると、基準はOR条件で結合され、いずれかが真の場合は常に満たされることがわかりました。

df[((df.A==1) == True) | ((df.D==6) == True)]
于 2015-03-25T04:00:24.160 に答える
9

私の答えは他の人と似ています。新しい関数を作成したくない場合は、パンダがすでに定義しているものを使用できます。パイプ方式を使用してください。

df.pipe(lambda d: d[d['column'] == value])
于 2016-05-27T19:00:59.680 に答える
7

loc行だけでなく列でもフィルタリングするためにを使用してデモンストレーションを追加したいだけで、連鎖操作のいくつかのメリットがあります。

以下のコードは、値で行をフィルタリングできます。

df_filtered = df.loc[df['column'] == value]

少し変更することで、列をフィルタリングすることもできます。

df_filtered = df.loc[df['column'] == value, ['year', 'column']]

では、なぜ連鎖メソッドが必要なのですか?答えは、多くの操作がある場合は読みやすいということです。例えば、

res =  df\
    .loc[df['station']=='USA', ['TEMP', 'RF']]\
    .groupby('year')\
    .agg(np.nanmean)
于 2018-01-29T06:18:36.400 に答える
5

すべての一般的なブールマスクと汎用マスクを適用する場合は、次のファイルをファイルに入れて、次のようにすべてを割り当てることができます。

pd.DataFrame = apply_masks()

使用法:

A = pd.DataFrame(np.random.randn(4, 4), columns=["A", "B", "C", "D"])
A.le_mask("A", 0.7).ge_mask("B", 0.2)... (May be repeated as necessary

これは少しハッキーですが、フィルターに従ってデータセットを継続的に切り刻んで変更している場合は、状況が少しきれいになる可能性があります。gen_mask関数には、上記のDaniel Velkovから採用された汎用フィルターもあります。これは、ラムダ関数で使用することも、必要に応じて使用することもできます。

保存するファイル(私はmasks.pyを使用します):

import pandas as pd

def eq_mask(df, key, value):
    return df[df[key] == value]

def ge_mask(df, key, value):
    return df[df[key] >= value]

def gt_mask(df, key, value):
    return df[df[key] > value]

def le_mask(df, key, value):
    return df[df[key] <= value]

def lt_mask(df, key, value):
    return df[df[key] < value]

def ne_mask(df, key, value):
    return df[df[key] != value]

def gen_mask(df, f):
    return df[f(df)]

def apply_masks():

    pd.DataFrame.eq_mask = eq_mask
    pd.DataFrame.ge_mask = ge_mask
    pd.DataFrame.gt_mask = gt_mask
    pd.DataFrame.le_mask = le_mask
    pd.DataFrame.lt_mask = lt_mask
    pd.DataFrame.ne_mask = ne_mask
    pd.DataFrame.gen_mask = gen_mask

    return pd.DataFrame

if __name__ == '__main__':
    pass
于 2013-04-18T04:44:28.577 に答える
4

このソリューションは、実装の点ではよりハックですが、使用法の点でははるかにクリーンであり、他の提案よりも確かに一般的です。

https://github.com/toobaz/generic_utils/blob/master/generic_utils/pandas/where.py

リポジトリ全体をダウンロードする必要はありません。ファイルを保存して実行します。

from where import where as W

十分なはずです。次に、次のように使用します。

df = pd.DataFrame([[1, 2, True],
                   [3, 4, False], 
                   [5, 7, True]],
                  index=range(3), columns=['a', 'b', 'c'])
# On specific column:
print(df.loc[W['a'] > 2])
print(df.loc[-W['a'] == W['b']])
print(df.loc[~W['c']])
# On entire - or subset of a - DataFrame:
print(df.loc[W.sum(axis=1) > 3])
print(df.loc[W[['a', 'b']].diff(axis=1)['b'] > 1])

少し愚かな使用例:

data = pd.read_csv('ugly_db.csv').loc[~(W == '$null$').any(axis=1)]

ちなみに、ブール値のcolを使用している場合でも、

df.loc[W['cond1']].loc[W['cond2']]

よりもはるかに効率的である可能性があります

df.loc[W['cond1'] & W['cond2']]

cond2がどこにあるかだけを評価するからcond1ですTrue

免責事項:私はこれを見たことがなかったので、私は最初に他の場所でこの答えを出しました。

于 2017-11-27T18:12:09.100 に答える
4

df値をフィルタリングする前に変数に割り当てる必要があるため、これは魅力的ではありません。

df[df["column_name"] != 5].groupby("other_column_name")

[]動作しているようです。オペレーターをネストすることもできます。たぶん、あなたが質問したので、彼らはそれを追加しました。

于 2018-04-19T08:17:01.467 に答える
3

論理演算にnumpyライブラリを活用することもできます。そのかなり速い。

df[np.logical_and(df['A'] == 1 ,df['B'] == 6)]
于 2018-01-25T07:22:23.910 に答える
2

列をインデックスとして検索するように設定すると、を使用DataFrame.xs()して断面を作成できます。これはquery答えほど用途が広いわけではありませんが、状況によっては役立つ場合があります。

import pandas as pd
import numpy as np

np.random.seed([3,1415])
df = pd.DataFrame(
    np.random.randint(3, size=(10, 5)),
    columns=list('ABCDE')
)

df
# Out[55]: 
#    A  B  C  D  E
# 0  0  2  2  2  2
# 1  1  1  2  0  2
# 2  0  2  0  0  2
# 3  0  2  2  0  1
# 4  0  1  1  2  0
# 5  0  0  0  1  2
# 6  1  0  1  1  1
# 7  0  0  2  0  2
# 8  2  2  2  2  2
# 9  1  2  0  2  1

df.set_index(['A', 'D']).xs([0, 2]).reset_index()
# Out[57]: 
#    A  D  B  C  E
# 0  0  2  2  2  2
# 1  0  2  1  1  0
于 2017-07-26T03:35:33.333 に答える
1

つまり、分析の準備ができたデータをサブセット化するときは、2つのことを行うということです。

  • 行を取得
  • 列を取得する

Pandasには、これらのそれぞれを実行するいくつかの方法と、行列を取得するのに役立ついくつかの手法があります。新しいパンダユーザーにとっては、選択肢がたくさんあるので混乱する可能性があります。

iloc、loc、brackets、query、isin、np.where、maskなどを使用していますか...

メソッドチェーン

現在、メソッドチェーンは、データラングリング時に機能する優れた方法です。Rでは、select()列とfilter()行という簡単な方法があります。

したがって、Pandasで物事を単純にしたい場合は、filter()for列とquery()for行を使用しないでください。これらは両方ともデータフレームを返すため、ブールインデックスをいじくり回す必要はなくdf[ ]、戻り値を追加する必要もありません。

それで、それはどのように見えますか:-

df.filter(['col1', 'col2', 'col3']).query("col1 == 'sometext'")

次に、、、などgroupbyの他のメソッドをチェーンできます。dropna()sort_values()reset_index()

一貫性をfilter()保ち、列のquery()取得と行の取得に使用することで、しばらくしてコードに戻ったときにコードを読みやすくなります。

しかし、フィルターは行を選択できますか?

はい、これは当てはまりますが、デフォルトでquery()は行と列をfilter()取得します。したがって、デフォルトを使用する場合は、axis=パラメーターを使用する必要はありません。

query()

query()は両方で使用できますand//比較演算子も使用できます。ではなく、でPythonを使用することもできます。or &|> , < , >= , <=, ==, !=

@my_listを使用して、クエリにリストを渡すことができます

クエリを使用して行を取得する例

df.query('A > B')

df.query('a not in b')

df.query("series == '2206'")

df.query("col1 == @mylist")

df.query('Salary_in_1000 >= 100 & Age < 60 & FT_Team.str.startswith("S").values')

フィルター()

df[]したがって、フィルターは基本的にブラケットをdf[[]]使用するのと同じであり、ラベルを使用して列を選択します。ただし、角かっこ表記以上のことを行います。

filterにはlike=、部分的な名前の列を選択するのに役立つparamがあります。

df.filter(like='partial_name',)

フィルタには、選択に役立つ正規表現もあります

df.filter(regex='reg_string')

したがって、この作業方法を要約すると、これまでの状況では機能しない可能性があります。たとえば、インデックス作成/スライスを使用する場合は、ilocが最適です。しかし、これは確かな作業方法のようであり、ワークフローとコードを簡素化できます。

于 2022-01-26T22:27:00.627 に答える