LoginSignup
0
0

ソートされてないMultiIndexの列を持つDataFrameで、groupbyで演算すると`PerformanceWarning`が発生するときがある

Last updated at Posted at 2023-06-02

環境

  • 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","")を渡したときで、なぜ挙動が違うのかを教えてもらいました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0