先日、pythonでpandasのデータフレーム をいじっていて、条件に該当するところだけ取り出そうとしていたのですが、"UserWarning: Boolean Series key will be reindexed to match DataFrame index."というエラーが出てきてしまいました。
ところが、結果を見ると求めたいものが出ていたので、これでいいのかなぁと放置しようかと思いましたが、せっかくなので原因を調査しましたので、その備忘メモです。
PythonのPandasでデータフレーム を作成して条件に合うものだけを得ようとしたらエラーに
実際に使用していたデータとは違いますが、以下のようなデータフレーム を使用していたイメージです。col1 | col2 | col3 | |
---|---|---|---|
0 | 1 | 2 | 3 |
1 | 1 | 2 | 30 |
2 | 1 | 2 | 300 |
3 | 1 | 20 | 3 |
4 | 1 | 20 | 30 |
5 | 1 | 20 | 300 |
6 | 1 | 200 | 3 |
7 | 1 | 200 | 30 |
8 | 1 | 200 | 300 |
9 | 10 | 2 | 3 |
10 | 10 | 2 | 30 |
11 | 10 | 2 | 300 |
12 | 10 | 20 | 3 |
13 | 10 | 20 | 30 |
14 | 10 | 20 | 300 |
15 | 10 | 200 | 3 |
16 | 10 | 200 | 30 |
17 | 10 | 200 | 300 |
18 | 10 | 2 | 3 |
19 | 100 | 2 | 30 |
20 | 100 | 2 | 300 |
21 | 100 | 20 | 3 |
22 | 100 | 20 | 30 |
23 | 100 | 20 | 300 |
24 | 100 | 200 | 3 |
25 | 100 | 200 | 30 |
26 | 100 | 200 | 300 |
27 | 100 | 2 | 3 |
28 | 100 | 2 | 30 |
29 | 100 | 2 | 300 |
これをデータフレーム に入れ込むため、クリップボードにコピーしてから下記のように実行します。
import pandas as pd df = pd.read_clipboard()
欲しいデータは"col1"が100で"col2"が200に該当するところだけ
この時抽出したかったのは、上記dfのうち
col1=100
かつ
col2=200
に該当する場所だけでしたので、特に考えずに
df[df["col1"]==100][df["col2"]==200]
と実行したのですが、なんと
__main__:1: UserWarning: Boolean Series key will be reindexed to match DataFrame index. col1 col2 col3 24 100 200 3 25 100 200 30 26 100 200 300
とwarningが出ました。
(でも欲しい結果は得られている)
原因は次元の違うものを取り入れていたから
そもそもなぜこういうやり方にしたかというと
1.まずは"col1"に関して以下のように実行したら
df[df["col1"]==100]
col1が100に該当する場所だけが以下のように出されます。
col1 col2 col3 19 100 2 30 20 100 2 300 21 100 20 3 22 100 20 30 23 100 20 300 24 100 200 3 25 100 200 30 26 100 200 300 27 100 2 3 28 100 2 30 29 100 2 300
ここからさらにcol2が200に該当するものを選ぼうとすると
df[df["col1"]==100]["col2"]==200
と実行すれば
19 False 20 False 21 False 22 False 23 False 24 True 25 True 26 True 27 False 28 False 29 False
となったので、該当する場所だけを手に入れられるようにboolean型のSeriesを使用して得られると思ったのですが、
df[df["col1"]==100][df["col2"]==200]
と実行すると上で書いたエラー(warning)が出てしまいました。
これは、df[df["col1"]==100]とdf["col2"]==200の長さが異なっていたからです。
実際に
len(df[df["col1"]==100]) len(df["col2"]==200)
とすると、それぞれ
11 30
となります。
解決策
長さが異なるものを使っていた(短い方に長いものを入れていた)のであれば、単に長さを揃えるようにしてやればいいので、
df[ (df["col1"]==100) & (df["col2"]==200)]
とやってやれば、
col1 col2 col3 24 100 200 3 25 100 200 30 26 100 200 300
と欲しいものが出てきます。