在 Pandas DataFrame 的多列上使用 fillna 方法失败

Using fillna method on multiple columns of a Pandas DataFrame failed

为什么这个操作会失败? 例如:

a = pd.DataFrame({'a': [1,2,np.nan, np.nan],
                 'b': [5,np.nan,6, np.nan],
                 'c': [5, 1, 5, 2]})


a[['a', 'b']].fillna(0, inplace=True)

并给了我这个警告:

SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

但是 a 仍然像以前一样充满了 NA。但是,如果我分别在每一列上调用 .fillna(),就不会有问题。如何一次性在多列中填充 NA 值?

这些答案的依据是 OP 希望对现有数据框进行就地编辑。通常,我会用一个新数据框覆盖现有数据框。


使用 pandas.DataFrame.fillnadict

Pandas fillna 允许我们传递一个字典,指定将填充哪些列以及填充什么。

所以这会起作用

a.fillna({'a': 0, 'b': 0})

     a    b  c
0  1.0  5.0  5
1  2.0  0.0  1
2  0.0  6.0  5
3  0.0  0.0  2

通过以下方式实现就地编辑:

a.fillna({'a': 0, 'b': 0}, inplace=True)

注意:我本来会这样做的 a = a.fillna({'a': 0, 'b': 0})

我们不保存文本长度,但我们可以使用 dict.fromkeys

变得可爱
a.fillna(dict.fromkeys(['a', 'b'], 0), inplace=True)

loc

我们可以使用与 OP 相同的格式,但使用 loc

将其放在正确的列中
a.loc[:, ['a', 'b']] = a[['a', 'b']].fillna(0)

a

     a    b  c
0  1.0  5.0  5
1  2.0  0.0  1
2  0.0  6.0  5
3  0.0  0.0  2

pandas.DataFrame.update

明确地使用另一个数据框的非空值进行就地编辑

a.update(a[['a', 'b']].fillna(0))

a

     a    b  c
0  1.0  5.0  5
1  2.0  0.0  1
2  0.0  6.0  5
3  0.0  0.0  2

逐列迭代

我真的不喜欢这种方法,因为它不必要地冗长

for col in ['a', 'b']:
    a[col].fillna(0, inplace=True)

a

     a    b  c
0  1.0  5.0  5
1  2.0  0.0  1
2  0.0  6.0  5
3  0.0  0.0  2

fillna 带有数据帧

使用 a[['a', 'b']].fillna(0) 的结果作为另一个 fillna 的输入。在我看来,这是愚蠢的。只用第一个选项。

a.fillna(a[['a', 'b']].fillna(0), inplace=True)

a

     a    b  c
0  1.0  5.0  5
1  2.0  0.0  1
2  0.0  6.0  5
3  0.0  0.0  2

编辑:正如@piRSquared 指出的那样,第一个解决方案应该是

a.loc[:, ['a', 'b']] = a[['a', 'b']].fillna(0)

在选定的列中填写

a.fillna(0, inplace = True)

填写所有栏目