環境
- Python 3.11.2
- pandas 2.0.2
起きたこと
列がMultiIndex
で、列名がソートされていないDataFrameがあります。
In [474]: df = pandas.DataFrame({("x","a"):[1,2,3],("y",""):["a","b","b"],("x","b"):[5,6,7]})
In [481]: df
Out[481]:
x y x
a b
0 1 a 5
1 2 b 6
2 3 b 7
このDataFrameに対して列"y"
をキーにしてgroupby
で演算すると、PerformanceWarning
が発生しました。
In [485]: tmp = df.groupby("y")
In [486]: tmp.sum()
<ipython-input-486-d2970d0aff60>:1: PerformanceWarning: dropping on a non-lexsorted multi-index without a level parameter may impact performance.
tmp.sum()
Out[486]:
x
a b
y
a 1 5
b 5 13
「level
引数なしでソートされていない"multi-index"を削除した」とみなされたようです。
明示的に列を削除している訳ではありませんが、pandas.core.groupby.DataFrameGroupBy.sum関数からpandas.DataFrame.drop関数が呼ばれていました。
具体的な関数呼び出しは以下の通りです。
pandas.core.groupby.DataFrameGroupBy.sum -> pandas.core.groupby.DataFrameGroupBy._reindex_output -> pandas.DataFrame.drop
対策
groupby
に"y"
ではなく("y","")
を指定すれば、PerformanceWarning
は発生しません。
In [476]: df.groupby(("y","")).sum()
Out[476]:
x
a b
(y, )
a 1 5
b 5 13
またメッセージ通り、列がソートされていればPerformanceWarning
は発生しません。
In [477]: df1 = pandas.DataFrame({("x","a"):[1,2,3],("x","b"):[5,6,7],("y",""):["a","b","b"]})
In [478]: df1
Out[478]:
x y
a b
0 1 5 a
1 2 6 b
2 3 7 b
In [480]: df1.groupby("y").sum()
Out[480]:
x
a b
y
a 1 5
b 5 13
補足
groupby
に"y"
を渡したときと("y","")
を渡したときで、なぜ挙動が違うのかを教えてもらいました。