用 pandas 数据框中另一列的值填充多列中的 Na

Posted

技术标签:

【中文标题】用 pandas 数据框中另一列的值填充多列中的 Na【英文标题】:Fill Na in multiple columns with values from another column within the pandas data frame 【发布时间】:2019-12-09 17:19:37 【问题描述】:

熊猫版0.23.4,python版3.7.1 我有一个数据框 df 如下

df = pd.DataFrame([[0.1, 2, 55, 0,np.nan],
                   [0.2, 4, np.nan, 1,99],
                   [0.3, np.nan, 22, 5,88],
                   [0.4, np.nan, np.nan, 4,77]],
                   columns=list('ABCDE'))
     A    B     C  D     E
0  0.1  2.0  55.0  0   NaN
1  0.2  4.0   NaN  1  99.0
2  0.3  NaN  22.0  5  88.0
3  0.4  NaN   NaN  4  77.0

我想将BC 列中的 Na 值替换为“A”列中的值。

预期输出是

     A   B      C    D      E 
0   0.1  2.0    55.0   0    NaN 
1   0.2  4.0    0.2    1    99.0 
2   0.3  0.3    22.0   5    88.0 
3   0.4  0.4    0.4    4    77.0

我已经尝试使用 fillaxis 0 进行填充,但它没有给出预期的输出,(它从上列填充)

df.fillna(method='ffill',axis=0, inplace = True)
    A    B     C   D     E
0  0.1  2.0  55.0  0   NaN
1  0.2  4.0  55.0  1  99.0
2  0.3  4.0  22.0  5  88.0
3  0.4  4.0  22.0  4  77.0  

df.fillna(method='ffill',axis=1, inplace = True)

输出:NotImplementedError:

也试过了

df[['B','C']] = df[['B','C']].fillna(df.A)
output:
    A    B     C   D     E
0  0.1  2.0  55.0  0   NaN
1  0.2  4.0   NaN  1  99.0
2  0.3  NaN  22.0  5  88.0
3  0.4  NaN   NaN  4  77.0

尝试使用0 填充BC 中的所有Na,使用inplace,但这也没有给出预期的输出

df[['B','C']].fillna(0,inplace=True)
output:
     A    B     C  D     E
0  0.1  2.0  55.0  0   NaN
1  0.2  4.0   NaN  1  99.0
2  0.3  NaN  22.0  5  88.0
3  0.4  NaN   NaN  4  77.0

如果分配回同一子集,则将0 填充到数据帧切片将起作用

df[['B','C']] = df[['B','C']].fillna(0)
output:
     A    B     C  D     E
0  0.1  2.0  55.0  0   NaN
1  0.2  4.0   0.0  1  99.0
2  0.3  0.0  22.0  5  88.0
3  0.4  0.0   0.0  4  77.0

1) 如何使用给定数据框中的列 A 中的值填充列 BC 中的 na 值? 2) 还有为什么在数据框的子集上使用 fillna 时 inlace 不起作用。 3) ffill 沿行怎么做(实现了吗)?

【问题讨论】:

【参考方案1】:

1) 如何使用给定数据框中的 A 列中的值填充 BandC 列中的 na 值?

由于没有实现按列替换,可能的解决方案是双重转置:

df[['B','C']] = df[['B','C']].T.fillna(df['A']).T
print (df)
     A    B     C  D     E
0  0.1  2.0  55.0  0   NaN
1  0.2  4.0   0.2  1  99.0
2  0.3  0.3  22.0  5  88.0
3  0.4  0.4   0.4  4  77.0

或者:

m = df[['B','C']].isna()
df[['B','C']] = df[['B','C']].mask(m, m.astype(int).mul(df['A'], axis=0))
print (df)
     A    B     C  D     E
0  0.1  2.0  55.0  0   NaN
1  0.2  4.0   0.2  1  99.0
2  0.3  0.3  22.0  5  88.0
3  0.4  0.4   0.4  4  77.0

2) 还有为什么在数据框的子集上使用 fillna 时 inlace 不起作用。

我认为原因是chained assignments,需要重新分配。

3)如何沿行填充(是否实现)?

如果分配回来,则替换为前向填充效果很好:

df1 = df.fillna(method='ffill',axis=1)
print (df1)
     A    B     C    D     E
0  0.1  2.0  55.0  0.0   0.0
1  0.2  4.0   4.0  1.0  99.0
2  0.3  0.3  22.0  5.0  88.0
3  0.4  0.4   0.4  4.0  77.0

df2 = df.fillna(method='ffill',axis=0)
print (df2)
     A    B     C  D     E
0  0.1  2.0  55.0  0   NaN
1  0.2  4.0  55.0  1  99.0
2  0.3  4.0  22.0  5  88.0
3  0.4  4.0  22.0  4  77.0

【讨论】:

您能否建议为什么ffill 不能像axis=0 一样正常工作,它没有实现吗? @Shijith - 我认为是错误 - 组合 inplace=Trueffill 谢谢,不知道在ffill 中分配回来会起作用。

以上是关于用 pandas 数据框中另一列的值填充多列中的 Na的主要内容,如果未能解决你的问题,请参考以下文章

用 Pandas 将 DataFrame 中某些列和行的值替换为同一 DataFrame 中另一列的值

根据火花数据框中另一列的值查找列的最大值?

如何通过 Pyspark 中同一数据框中另一列的正则表达式值过滤数据框中的一列

将语料库中的名称部分匹配到 Pandas 数据框中另一列中的名称

Pyspark如何将一列与数据框中另一列的结果相乘?

如果同一行中另一列中的值匹配,如何比较列的两个值