たくさん寝太郎の寝床

料理とITと皿回しが好きなオタクのブログ

pandasの話

こんにちは、たくさん寝太郎です。

この前pandasのDataFrameを使うときにちょっと悩んだことがあったのでメモを残しておきます。


次のようなcsvファイルがあったときに、「プラント圧力=高」かつ「鋼の色=青」を満たすものを除いたデータを得たいとします。

プラント圧力,煙の色,鋼の色,プラント状態
低,白,青,good
高,黒,茶,bad
高,黒,青,bad
高,赤,青,good
低,黒,青,bad
高,白,茶,bad
低,白,茶,bad
高,白,青,good


まず最初に考えたのは次の方法でした。

df[(df['プラント圧力']!='高') | (df['鋼の色']!='青')]

=>

  プラント圧力 煙の色 鋼の色 プラント状態
0      低   白   青   good
1      高   黒   茶    bad
4      低   黒   青    bad
5      高   白   茶    bad
6      低   白   茶    bad

これで良さそうですが、今回考えていたものでは出てきた条件が2つか3つか、何個になるか分からなかったのでもっと良さそうな方法がないか考えました。

条件の属性をattributes,パターンをpatternsとしてリスト型に格納します。

attributes = ['プラント圧力','鋼の色']
patterns = ['高','青']

色々と調べた結果リスト内包記法とanyを使えば良さそうでした。

ex_data = ~df[attributes].isin(patterns)
ex_data = df[[any(ex_data.values[i]) for i in range(len(df))]]

1行目のex_dataでは次のような真理値のDataFrameが返ってきます。

   プラント圧力    鋼の色
0    True  False
1   False   True
2   False  False
3   False  False
4    True  False
5   False   True
6    True   True
7   False  False

リスト内包記法を使ってany(ex_data.values[i])で各行のORを取った真理値のリストを得て、dfで行抽出すれば求めたい結果が出てきました。


これだと条件が複数個あっても大丈夫です。
もっと楽な方法があったらコメントで教えてください。