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

Jam*_*ong 5 python pandas na

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

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)
Run Code Online (Sandbox Code Playgroud)

并给了我这个警告:

SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame
Run Code Online (Sandbox Code Playgroud)

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

piR*_*red 8

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


使用pandas.DataFrame.fillnadict

熊猫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
Run Code Online (Sandbox Code Playgroud)

通过就地编辑,可以实现:

a.fillna({'a': 0, 'b': 0}, inplace=True)
Run Code Online (Sandbox Code Playgroud)

注意:我会做这个a = a.fillna({'a': 0, 'b': 0})

我们不保存文本长度,但使用起来会很可爱 dict.fromkeys

a.fillna(dict.fromkeys(['a', 'b'], 0), inplace=True)
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

逐列迭代

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

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)