Python dataframe fillna()只保留部分列

Python dataframe fillna()只保留部分列,python,pandas,dataframe,Python,Pandas,Dataframe,我试图在Pandas数据框中仅对某些列子集使用0填充none值 当我这样做时: import pandas as pd df = pd.DataFrame(data={'a':[1,2,3,None],'b':[4,5,None,6],'c':[None,None,7,8]}) print df df.fillna(value=0, inplace=True) print df 输出: a b c 0 1.0 4.0 NaN 1 2.0 5.0 NaN 2

我试图在Pandas数据框中仅对某些列子集使用0填充none值

当我这样做时:

import pandas as pd
df = pd.DataFrame(data={'a':[1,2,3,None],'b':[4,5,None,6],'c':[None,None,7,8]})
print df
df.fillna(value=0, inplace=True)
print df
输出:

     a    b    c
0  1.0  4.0  NaN
1  2.0  5.0  NaN
2  3.0  NaN  7.0
3  NaN  6.0  8.0
     a    b    c
0  1.0  4.0  0.0
1  2.0  5.0  0.0
2  3.0  0.0  7.0
3  0.0  6.0  8.0
它将每个
None
替换为
0
。我想做的是,只替换列
a
b
中的
None
s,而不是
c


执行此操作的最佳方法是什么?

您可以选择所需的列,并通过分配来执行:

df[['a', 'b']] = df[['a','b']].fillna(value=0)
结果输出如预期:

     a    b    c
0  1.0  4.0  NaN
1  2.0  5.0  NaN
2  3.0  0.0  7.0
3  0.0  6.0  8.0

您可以对不同的列使用具有不同值的
dict
fillna

df.fillna({'a':0,'b':0})
Out[829]: 
     a    b    c
0  1.0  4.0  NaN
1  2.0  5.0  NaN
2  3.0  0.0  7.0
3  0.0  6.0  8.0
在把它分配回来之后

df=df.fillna({'a':0,'b':0})
df
Out[831]: 
     a    b    c
0  1.0  4.0  NaN
1  2.0  5.0  NaN
2  3.0  0.0  7.0
3  0.0  6.0  8.0

您可以避免使用Wen的解决方案和inplace=True复制对象:

df.fillna({'a':0,'b':0},inplace=True)
打印(df)
这将产生:

     a    b    c
0  1.0  4.0  NaN
1  2.0  5.0  NaN
2  3.0  0.0  7.0
3  0.0  6.0  8.0
或者类似于:

df.loc[df['a'].isnull(),'a']=0
df.loc[df['b'].isnull(),'b']=0
如果还有更多:

for i in your_list:
    df.loc[df[i].isnull(),i]=0

以下是如何在一行中完成这一切:

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

细分:
df[['a',b']]
选择要填充NaN值的列,
value=0
告诉它用零填充NaN,并且
inplace=True
将使更改永久化,而不必复制对象。

使用顶部答案会产生关于更改df切片副本的警告。假设您有其他列,更好的方法是传递字典:

df.fillna({'A':'NA','B':'NA'},inplace=True)

有时这种语法不起作用:

df[['col1','col2']] = df[['col1','col2']].fillna()
请改用以下方法:

df['col1','col2']

出于某种奇怪的原因,这不起作用(使用熊猫:“0.25.1”)

另一个解决方案:

subset_cols = ['col1','col2']
[df[col].fillna(0, inplace=True) for col in subset_cols]
例如:

df = pd.DataFrame(data={'col1':[1,2,np.nan,], 'col2':[1,np.nan,3], 'col3':[np.nan,2,3]})
输出:

   col1  col2  col3
0  1.00  1.00   nan
1  2.00   nan  2.00
2   nan  3.00  3.00
应用列表组件。要填充NA值,请执行以下操作:

subset_cols = ['col1','col2']
[df[col].fillna(0, inplace=True) for col in subset_cols]
输出:

   col1  col2  col3
0  1.00  1.00   nan
1  2.00  0.00  2.00
2  0.00  3.00  3.00

这应该是有效的,没有任何警告

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

是的,这正是我想要的!非常感谢。有什么方法可以做到这一点吗?我的原始数据帧相当大。我认为这样做不会带来任何性能提升,因为您正在覆盖原始df。loc在这里是多余的,
df[['a','b']]=df[['a','b']]。fillna(value=0)
仍然会work@EdChum它是否会产生一个临时数据帧,因此需要更多的内存?(我更关心的是内存而不是时间复杂性。)对于许多操作,
inplace
仍然可以在副本上工作。我不知道fillna的情况是否如此。从pandas的一位核心开发人员那里可以看到。真的很酷,顺便说一句,对于dict,如果您愿意,您可以使用
fromkeys
,+1答案/示例,如果它实际为不同的列显示了不同的值,那么它会更清晰。@RufusVS这是正确的,但仍然尝试匹配op的预期输出。这是比公认答案更好的解决方案,因为它避免了链式索引问题,例如,如果与
df.fillna({'a':0,'b':0},inplace=True)一起使用
,虽然这是正确的,但避免复制。不知何故,这会给出带有copyWarning的设置,并且更改不会反映在
df
中。我认为
inplace
不是一个好的实践,检查,所以最好的方法应该是,在我看来,如果提高
就地
警告,然后从熊猫身上移除。这么简单的建议-总是避免就地,永远不要出现这样的问题;)
df[['a', 'b']] = df.loc[:,['a', 'b']].fillna(value=0)