我想替换以下 C
列 D
和 pd.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)
有没有其他方法可以替换缺失值,而不必为每一列编写一行代码?
答案 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)