1. 抽出条件のパラメータ化
データの抽出条件をパラメータ化したい。
こう思ったことが何度もありました。
今までは複雑な条件は対応できなかったり、対応できたとしても実装が複雑になってしまって使い物にならなかったりで諦めてきました。
ただ今回は違います。
抽出条件のパラメータ化をかなり汎用的に対応できて実装もそれなりに簡単にできる方法を考えました。
使用するのは
です。
1.1. pandas.Series.isinではない
使用するのはpandas.Series.isinではありません。
Series.isinは皆様普通に使いこなしていると思います。
今回は DataFrame.isinを使用する ことが肝です。
1.2. pandas.DataFrame.isinでは引数に辞書型を指定できる
DataFrame.isinでは辞書型を指定できます。
このことによって 異なる列に異なる抽出条件を一括で指定 できます。
今回はこの機能を使って抽出条件のパラメータ化を実装してみます。
2. DataFrame.isinを試してみる
実際に試してみて動作を確認します。
2.1. データの準備
データはseabornのtipsを使用します。
列が多すぎるの使用する3列だけに絞り込んだデータを使用します。
データ作成のコードがこちらです。
import pandas as pd
import seaborn as sns
tips = (
sns.load_dataset('tips')
[[
'total_bill',
'sex',
'smoker',
]]
)
実際のデータがこちらです。
total_bill sex smoker
0 16.99 Female No
1 10.34 Male No
2 21.01 Male No
3 23.68 Male No
4 24.59 Female No
2.2. リスト型で条件を指定してみる
動作を確認するためリスト型で条件を指定してみます。
tips.isin(
['Male']
)
total_bill sex smoker
0 False False False
1 False True False
2 False True False
3 False True False
4 False False False
.. ... ... ...
239 False True False
240 False False False
241 False True False
242 False True False
243 False False False
対象の列は指定できないので列に関係なく値が’Male’の箇所がTrueになります。
列を指定できないと少し扱いづらいです。
列を指定するためには辞書型の引数を使用 します。
2.3. 辞書型のパラメータを作成する
下記の条件のパラメータを辞書型で作成します
-
smoker: Yes
-
sex: Female
conditions={
'smoker': ['Yes'],
'sex': ['Female'],
}
2.4. 辞書型の条件を適用する
実際に適用してみます。
tips.isin(conditions)
total_bill sex smoker
0 False True False
1 False False False
2 False False False
3 False False False
4 False True False
.. ... ... ...
239 False False False
240 False True True
241 False False True
242 False False False
243 False True False
sex==Femaleの箇所がTrue、smoker==Yesの箇所がTrue になっています。
パラメータで指定していない列:total_billも結果に含まれていてすべてがFalseになっています。
指定していない列があると邪魔 なので指定していない列を除外する方法を検討します。
2.5. 条件指定してしない列を除外する
conditions.keys()を使用して関係ない列は除外します。
実際のコードはこうなります。
(
tips
[
conditions.keys()
]
.isin(conditions)
)
smoker sex
0 False True
1 False False
2 False False
3 False False
4 False True
.. ... ...
239 False False
240 True True
241 True False
242 False False
243 False True
指定した列だけの結果を取得できました。
2.6. allを使用してand条件を実現する
allを使用してand条件を実現します。
つまり 女性で喫煙者 の場合にTrueを取得します。
コードはこうなります。
(
tips
[
conditions.keys()
]
.isin(conditions)
.all(axis=1)
)
0 False
1 False
2 False
3 False
4 False
...
239 False
240 True
241 False
242 False
243 False
and条件を実現できました。
2.7. anyを使用してor条件を実現する
anyを使用してor条件を実現します。
つまり 女性あるいは喫煙者 の場合にTrueを取得します。
コードはこうなります。
(
tips
[
conditions.keys()
]
.isin(conditions)
.any(axis=1)
)
0 True
1 False
2 False
3 False
4 True
...
239 False
240 True
241 True
242 False
243 True
or条件を実現できました。
3. 実際にデータ抽出してみます
試したことをまとめて実際にデータ抽出してみます。
3.1. 女性で喫煙者
女性かつ喫煙者のデータを抽出します。
Female_and_smoker=(
tips
.loc[
lambda x: (
x
[
conditions.keys()
]
.isin(conditions)
.all(axis=1)
)
]
)
Female_and_smoker.head(5)
total_bill sex smoker
67 3.07 Female Yes
72 26.86 Female Yes
73 25.28 Female Yes
92 5.75 Female Yes
93 16.32 Female Yes
3.2. 女性あるいは喫煙者
女性あるいは喫煙者のデータを抽出します。
Female_or_smoker=(
tips
.loc[
lambda x: (
x
[
conditions.keys()
]
.isin(conditions)
.any(axis=1)
)
]
)
Female_or_smoker.tail(10)
total_bill sex smoker
229 22.12 Female Yes
230 24.01 Male Yes
231 15.69 Male Yes
234 15.53 Male Yes
236 12.60 Male Yes
237 32.83 Male Yes
238 35.83 Female No
240 27.18 Female Yes
241 22.67 Male Yes
243 18.78 Female No
4. まとめ
複数の列に対する条件を辞書型で指定してデータ抽出できました。
指定した条件は allかanyのどちらかを使用することでand条件にもor条件にもすることが可能 です。
and条件やor条件がネストしてしまう複雑な抽出条件には対応できませんが簡単の抽出条件であれば便利に使えそうです。
今後は 抽出条件を辞書型パラメータで指定することでデータの条件抽出のコード共通化を進めることができそう です。
今回は以上です。