如何替换 Pandas 列子集上的 NaN 值?

时间:2021-01-20 18:00:35

标签: python pandas dataframe nan

我想替换以下 CDpd.DataFrame 上的缺失值:

df = pd.DataFrame({"A": [1,2,3], 
                   "B": [1, np.nan, 3],
                   "C": [np.nan, 2, 3],
                   "D": [1, 2, np.nan]})

df


    A   B       C       D
0   1   1.00    nan     1.00
1   2   nan     2.00    2.00
2   3   3.00    3.00    nan

如果逐列替换值,我可以做到:

df["C"].fillna(0, inplace=True)
df["D"].fillna(0, inplace=True)

但是,如果我尝试同时在两列上执行此操作,则会得到 SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame

df[["C", "D"]].fillna(0, inplace=True)

我也尝试使用 .loc 更改值,但它也不起作用:

df.loc[:,["C", "D"]].fillna(0, inplace=True)

有没有其他方法可以替换缺失值,而不必为每一列编写一行代码?

3 个答案:

答案 0 :(得分:1)

在编写问题时,我找到了一个可能的解决方案:

df[["C", "D"]] = df[["C", "D"]].fillna(0)

答案 1 :(得分:1)

你可以试试:

fill_map = {col:0 for col in ['C', 'D']}
df = df.fillna(value=fill_map)

df:

    A   B   C   D
0   1   1.0 0.0 1.0
1   2   NaN 2.0 2.0
2   3   3.0 3.0 0.0

答案 2 :(得分:1)

出现问题是因为在一种情况下您正在使用数据框的视图,而在另一种情况下您使用的是副本。

df["C"] 将视图返回到 df(数据系列)中,因此使用 .fillna(0, inplace=True) 更改它会更改实际的 df 数据帧。

然而,

df[["C", "D"]] 返回 df 一部分的副本,顺便说一下,由于双括号,df[["C"]] 也是如此。因此,如果您使用 .fillna(0, inplace=True) 更改它,则只会更改副本,因此您看不到原始 df 中的更改。这就是熊猫发出 SettingWithCopyWarning 警告的原因。

操作是返回视图还是数据帧副本的逻辑并不直观。 This 对此有一些详细信息。

您自己的解决方案

df[["C", "D"]] = df[["C", "D"]].fillna(0)

有效,因为您正在制作副本,用零填充它,然后将其重新分配给原始 df。

当有较大的列列表时,另一种解决方案是:

cols = ['C', 'D']
for c in cols: df[c].fillna(0, inplace=True)