※追記 2021
いつのバージョンからかは知らないが、今は.ixしないで↓でいける
df[df["B"].isnull()]
Pythonで色々なデータを扱う時に使うPandasですが、特定の数値を検索したりする時に今まで普通にfor
やdf.iterrows()
などで一列ずつ処理してました。
でもデータが大きくなると遅いんですよね。
何か良い方法がないか調べてみると、どうやらdf.ix[]
をマスク(フィルター?)として使うと良いみたいです。
例えばこんなデータフレームがあったとします。
print df
A B C D E
TIME
2001-01-08 06:00:00 -0.5925 -1.11 0.055023 -0.074103 0.129126
2001-01-08 06:05:00 -0.4213 NaN NaN NaN NaN
2001-01-08 06:10:00 -0.3613 -2.19 NaN NaN NaN
2001-01-08 06:15:00 -0.3613 NaN NaN NaN 0.224574
2001-01-08 06:20:00 -0.3613 NaN 0.129036 -0.000281 1.094003
2001-01-08 06:25:00 -0.8243 -0.65 0.137242 -0.022502 2.145931
行BでNaNになっている列を知りたい
print df.ix[df["B"].isnull()]
A B C D E
TIME
2001-01-08 06:05:00 -0.4213 NaN NaN NaN NaN
2001-01-08 06:15:00 -0.3613 NaN NaN NaN 0.224574
2001-01-08 06:20:00 -0.3613 NaN 0.129036 -0.000281 1.094003
行EでNaNになってない列を知りたい
print df.ix[df["E"].isnull()==False]
A B C D E
TIME
2001-01-08 06:00:00 -0.5925 -1.11 0.055023 -0.074103 0.129126
2001-01-08 06:15:00 -0.3613 NaN NaN NaN 0.224574
2001-01-08 06:20:00 -0.3613 NaN 0.129036 -0.000281 1.094003
2001-01-08 06:25:00 -0.8243 -0.65 0.137242 -0.022502 2.145931
どの行がNaNになっていても検索ヒット
print df.ix[df.isnull().values.any()]
A B C D E
TIME
2001-01-08 06:05:00 -0.4213 NaN NaN NaN NaN
2001-01-08 06:10:00 -0.3613 -2.19 NaN NaN NaN
2001-01-08 06:15:00 -0.3613 NaN NaN NaN 0.224574
2001-01-08 06:20:00 -0.3613 NaN 0.129036 -0.000281 1.094003
最初の3つの列で、行CがNaNになっている列だけ欲しい
print df.ix[df["C"].isnull(), :3]
A B C D E
TIME
2001-01-08 06:05:00 -0.4213 NaN NaN NaN NaN
2001-01-08 06:10:00 -0.3613 -2.19 NaN NaN NaN
行DでNaNになっている列の行AとBが欲しい
print df.ix[df["D"].isnull(), ["A", "B"]]
A B
TIME
2001-01-08 06:05:00 -0.4213 NaN
2001-01-08 06:10:00 -0.3613 -2.19
2001-01-08 06:15:00 -0.3613 Nan
行DでNaNになっている列の行Aの数値を操作(1引いてみる)
df.ix[df["D"].isnull(), "A"] -= 1
print df["A"]
A
TIME
2001-01-08 06:00:00 -0.5925
2001-01-08 06:05:00 -1.4213
2001-01-08 06:10:00 -1.3613
2001-01-08 06:15:00 -1.3613
2001-01-08 06:20:00 -0.3613
2001-01-08 06:25:00 -0.8243
上記の状態で条件検索
print df["A"]
A
TIME
2001-01-08 06:00:00 -0.5925
2001-01-08 06:05:00 -1.4213
2001-01-08 06:10:00 -1.3613
2001-01-08 06:15:00 -1.3613
2001-01-08 06:20:00 -0.3613
2001-01-08 06:25:00 -0.8243
print df.ix[df["A"]<= -1]
A B C D E
TIME
2001-01-08 06:05:00 -1.4213 NaN NaN NaN NaN
2001-01-08 06:10:00 -1.3613 -2.19 NaN NaN NaN
2001-01-08 06:15:00 -1.3613 NaN NaN NaN 0.224574
この例では小さいですが、大きなデータフレームでも全然早いです。
追記
各列の数値を複雑な条件式で操作をしたい場合などはdf.apply(function, axis=1)
がベストっぽい。