pandasで複数条件のand, or, notから行を抽出(選択)
pandasで複数の条件のand, or, notから行を抽出(選択)する方法を説明する。
注意点は以下の二つ。
&
、|
、~
を使う(and
、or
、not
だとエラー)- 比較演算子を使うときは条件ごとに括弧で囲む(括弧がないとエラー)
以下のようなエラーが出る。
and
、or
、not
を使ったときのエラー。
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
括弧がないときのエラー。
TypeError: cannot compare a dtyped [object] array with a scalar of type [bool]
なお、ここではブールインデックスを用いたレガシーな方法を説明するが、query()
メソッドを使うとより簡潔に書ける。以下の記事を参照。
今回は例として以下のデータを使用する。
import pandas as pd
df = pd.read_csv('data/src/sample_pandas_normal.csv')
print(df)
# name age state point
# 0 Alice 24 NY 64
# 1 Bob 42 CA 92
# 2 Charlie 18 CA 70
# 3 Dave 68 TX 70
# 4 Ellen 24 CA 88
# 5 Frank 30 NY 57
source: pandas_multiple_conditions.py
サンプルのcsvファイルはコチラ。
例はpandas.DataFrame
だが、pandas.Series
でも同様。
スポンサーリンク
行を抽出(選択)する方法
まず、pandas.DataFrame
から行を抽出(選択)して新しいpandas.DataFrame
を取得する方法を示す。
真偽値bool
のリスト(配列)またはpandas.Series
を使うと、True
の行だけが抽出(選択)できる。
mask = [True, False, True, False, True, False]
df_mask = df[mask]
print(df_mask)
# name age state point
# 0 Alice 24 NY 64
# 2 Charlie 18 CA 70
# 4 Ellen 24 CA 88
source: pandas_multiple_conditions.py
したがって、複数条件のand, or, notからbool
のリストまたはpandas.Series
を取得できればよい。
複数条件のand, or, notで行を抽出(選択)するコード例
2つの条件のandをとったbool
のpandas.Series
は、&
を使って以下のように取得できる。
print(df['age'] < 35)
# 0 True
# 1 False
# 2 True
# 3 False
# 4 True
# 5 True
# Name: age, dtype: bool
print(~(df['state'] == 'NY'))
# 0 False
# 1 True
# 2 True
# 3 True
# 4 True
# 5 False
# Name: state, dtype: bool
print((df['age'] < 35) & ~(df['state'] == 'NY'))
# 0 False
# 1 False
# 2 True
# 3 False
# 4 True
# 5 False
# dtype: bool
source: pandas_multiple_conditions.py
これを使ってTrue
の行だけを抽出(選択)する。
df_and = df[(df['age'] < 35) & ~(df['state'] == 'NY')]
print(df_and)
# name age state point
# 2 Charlie 18 CA 70
# 4 Ellen 24 CA 88
source: pandas_multiple_conditions.py
orも同様。|
を使う。
print((df['age'] < 20) | (df['point'] > 90))
# 0 False
# 1 True
# 2 True
# 3 False
# 4 False
# 5 False
# dtype: bool
df_or = df[(df['age'] < 20) | (df['point'] > 90)]
print(df_or)
# name age state point
# 1 Bob 42 CA 92
# 2 Charlie 18 CA 70
source: pandas_multiple_conditions.py
3個以上の条件では演算子の優先順位に注意
演算子としての優先順位は、高い順にnot(~
)、and(&
)、or(|
)。したがって、順番によって結果が異なる。
df_multi_1 = df[(df['age'] < 35) | ~(df['state'] == 'NY') & (df['point'] < 75)]
print(df_multi_1)
# name age state point
# 0 Alice 24 NY 64
# 2 Charlie 18 CA 70
# 3 Dave 68 TX 70
# 4 Ellen 24 CA 88
# 5 Frank 30 NY 57
df_multi_2 = df[(df['age'] < 35) & (df['point'] < 75) | ~(df['state'] == 'NY')]
print(df_multi_2)
# name age state point
# 0 Alice 24 NY 64
# 1 Bob 42 CA 92
# 2 Charlie 18 CA 70
# 3 Dave 68 TX 70
# 4 Ellen 24 CA 88
# 5 Frank 30 NY 57
source: pandas_multiple_conditions.py
まとまりごとに括弧で囲ったほうが無難。
df_multi_3 = df[((df['age'] < 35) | ~(df['state'] == 'NY')) & (df['point'] < 75)]
print(df_multi_3)
# name age state point
# 0 Alice 24 NY 64
# 2 Charlie 18 CA 70
# 3 Dave 68 TX 70
# 5 Frank 30 NY 57
source: pandas_multiple_conditions.py
スポンサーリンク