LoginSignup
0
0

列が`MultiIndex`でかつ重複しているDataFrameで、`fillna`に重複している列を指定するとRecursionErrorが発生する

Last updated at Posted at 2023-06-02

環境

  • Python 3.11.2
  • pandas 2.0.2
  • numpy 1.24.2

何が起きたのか?

列がMultiIndexで、かつ列が重複しているDataFrameがあります。

In [194]: data = [[numpy.nan, 2, 3], [4, numpy.nan, 6], [7, 8, numpy.nan]]

In [195]: data
Out[195]: [[nan, 2, 3], [4, nan, 6], [7, 8, nan]]


In [196]: df = pandas.DataFrame(data, columns=pandas.MultiIndex.from_tuples([("x","a"),("x","a"),("y","b")]))

In [197]: df
Out[197]: 
     x         y
     a    a    b
0  NaN  2.0  3.0
1  4.0  NaN  6.0
2  7.0  8.0  NaN

In [198]: df.columns
Out[198]: 
MultiIndex([('x', 'a'),
            ('x', 'a'),
            ('y', 'b')],
           )

pandas.DataFrame.fillnaで欠損値を0で埋めます。
重複している列("x","a")を指定すると、RecursionErrorが発生しました。

In [256]: df.fillna({("y","b"): 0})
Out[256]: 
     x         y
     a    a    b
0  NaN  2.0  3.0
1  4.0  NaN  6.0
2  7.0  8.0  0.0

In [257]: df.fillna({("x","a"): 0})
# 数分経った後にRecursionError発生
...
RecursionError: maximum recursion depth exceeded while calling a Python object

検証したこと

fillnainplace=Trueを指定する

inplace=Trueを指定すれば、問題なく実行できました。

In [259]: df.fillna({("x","a"): 0}, inplace=True)

In [260]: df
Out[260]: 
     x         y
     a    a    b
0  0.0  2.0  3.0
1  4.0  0.0  6.0
2  7.0  8.0  NaN

列がIndexの場合

列がMultiIndexではなくIndexであるDataFrameで検証しました。

In [261]: df2 = pandas.DataFrame(data, columns=["a","a","b"])

In [263]: df2
Out[263]: 
     a    a    b
0  NaN  2.0  3.0
1  4.0  NaN  6.0
2  7.0  8.0  NaN

In [264]: df2.columns
Out[264]: Index(['a', 'a', 'b'], dtype='object')

問題なく実行できました。

In [265]: df2.fillna({"b":0})
Out[265]: 
     a    a    b
0  NaN  2.0  3.0
1  4.0  NaN  6.0
2  7.0  8.0  0.0

In [266]: df2.fillna({"a":0})
Out[266]: 
     a    a    b
0  0.0  2.0  3.0
1  4.0  0.0  6.0
2  7.0  8.0  NaN

補足

issueを作成しました。

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