【问题标题】:Pandas SettingWithCopyWarning for fillna with MultiIndex DataFrame带有MultiIndex DataFrame的fillna的Pandas SettingWithCopyWarning
【发布时间】:2019-05-31 11:58:13
【问题描述】:

带有fillna() 的行会引发警告,即使它没有就地执行。这是为什么呢?

import pandas as pd
import numpy as np


tuples = [('foo', 1), ('foo', 2), ('bar', 1), ('bar', 2)]
index = pd.MultiIndex.from_tuples(tuples)

df = pd.DataFrame(np.random.randn(2, 4), columns=index)
df.loc[0, ('foo', 1)] = np.nan

# this works without warning
# df = pd.DataFrame({'foo': [1, np.nan, 3], 'bar': [np.nan, 22, 33]]})  

df1 = df[['foo', 'bar']]
# df1 = df[['foo', 'bar']].copy()  # this does not help
filled = df1.fillna({'foo': 100, 'bar': 200}, inplace=False)

如果foobar 是普通列,而不是多索引,则不会出现问题。

【问题讨论】:

  • df1 = df[['foo', 'bar']].copy() ?
  • 也抛出警告
  • 我只是在我的 Jupyter Notebook 中复制、粘贴和运行您的代码,但没有出现警告。为什么会这样?

标签: python pandas dataframe warnings nan


【解决方案1】:

这是一个误报,此处不应发出警告。我认为问题在于fillna 不理解“foo”和“bar”适用于 MultiIndex 列的特定级别。

我建议在实现此功能之前,在 GroupBy 内调用 fillna 作为解决方法。

fill = {'foo': 100, 'bar': 200}
df1.groupby(level=0, axis=1).apply(lambda x: x.fillna(fill[x.name]))

          foo                 bar          
            1         2         1         2
0  100.000000  1.040531 -1.516983 -0.866276
1   -0.055035 -0.107310  1.365467 -0.097696

或者,要直接使用fillna,指定元组的字典(因为,MultiIndex),

df1.fillna({('foo', 1): 100, ('foo', 2): 100})

          foo                 bar          
            1         2         1         2
0  100.000000  1.040531 -1.516983 -0.866276
1   -0.055035 -0.107310  1.365467 -0.097696

【讨论】:

  • 谢谢。我应用了第二个解决方案并且它有效:) 但实际上,它不是误报。在后台,pandas 执行了就地填充,可以在调试器中跟踪。在某些情况下,它给我留下了未填充的 nas。
  • @Rafcik 这是一个误报,因为SettingWithCopyWarning was developed to warn pandas users against bad practices 这样的链接分配。这里没有发生这样的事情。
猜你喜欢
  • 2016-02-04
  • 1970-01-01
  • 1970-01-01
  • 2017-03-28
  • 2016-12-28
  • 2019-02-24
  • 2015-05-31
  • 1970-01-01
  • 2019-05-20
相关资源
最近更新 更多