Pandas 从另一个数据框中填充数据框中的缺失值

Pandas fill missing values in dataframe from another dataframe

我找不到 pandas 函数(我以前见过)用另一个数据帧中的值替换数据帧中的 NaN(假设可以指定一个公共索引)。有帮助吗?

如果你有两个相同形状的DataFrame,那么:

df[df.isnull()] = d2

会成功的。

只有 df.isnull() 的计算结果为 True 的位置(以绿色突出显示)才有资格分配。

实际上,DataFrame 的大小/形状并不总是相同,转换方法(尤其是 .shift())很有用。

输入的数据总是脏的、不完整的或不一致的。课程的标准杆。有相当广泛的 pandas tutorial and associated cookbook 来处理这些情况。

正如我刚刚了解到的,有一个 DataFrame.combine_first() 方法,它正是这样做的,另外 属性 如果你更新的数据框 d2 比你原来的 df,还会添加额外的行和列。

df = df.combine_first(d2)

DataFrame.combine_first() 准确回答了这个问题。

但是,有时您想 fill/replace/overwrite DataFrame A 的一些非缺失(非 NaN)值与 DataFrame B 的值。这个问题把我带到了这个页面,解决方案是 DataFrame.mask()

A = B.mask(condition, A)

condition 为真时,将使用 A 的值,否则将使用 B 的值。

例如,您可以使用 mask 解决 OP 的原始问题,这样当 A 中的元素为非 NaN 时,使用它,否则使用 B 中的相应元素。

但是使用 DataFrame.mask() 可以用 B 的值替换不满足任意条件(小于零?大于 100?)的 A 值。因此 mask 更灵活,对这个问题有点矫枉过正,但我​​认为它值得一提(我需要它来解决我的问题)。

同样重要的是要注意 B 可能是一个 numpy 数组而不是 DataFrame。 DataFrame.combine_first() 要求 B 是一个 DataFrame,但是 DataFrame.mask() 只要求 B 是一个 NDFrame 并且它的尺寸与 A 的尺寸相匹配。

这应该很简单

df.fillna(d2)

一个专门的方法是 DataFrame.update:

引自文档:

Modify in place using non-NA values from another DataFrame.
Aligns on indices. There is no return value.

需要注意的重要一点是,此方法将修改您的数据inplace。所以它会覆盖你更新的数据框。

示例:

print(df1)
       A    B     C
aaa  NaN  1.0   NaN
bbb  NaN  NaN  10.0
ccc  3.0  NaN   6.0
ddd  NaN  NaN   NaN
eee  NaN  NaN   NaN

print(df2)
         A    B     C
index                
aaa    1.0  1.0   NaN
bbb    NaN  NaN  10.0
eee    NaN  1.0   NaN

# update df1 NaN where there are values in df2
df1.update(df2)
print(df1)
       A    B     C
aaa  1.0  1.0   NaN
bbb  NaN  NaN  10.0
ccc  3.0  NaN   6.0
ddd  NaN  NaN   NaN
eee  NaN  1.0   NaN

请注意 aaa, Aeee, B

交叉处更新的 NaN

其他答案中缺少的一个重要信息是 combine_firstfillna 都在索引上匹配,因此您必须使索引在 DataFrame 中匹配才能使这些方法起作用。

通常,需要在其他一些列上进行匹配以填充缺失值。在这种情况下,您需要先使用 set_index 来匹配要匹配的列,即索引。

df1 = df1.set_index(cols_to_be_matched).fillna(df2.set_index(cols_to_be_matched)).reset_index()

df1 = df1.set_index(cols_to_be_matched).combine_first(df2.set_index(cols_to_be_matched)).reset_index()

另一种选择是使用 merge:

df1 = (df1.merge(df2, on=cols_to_be_matched, how='left', suffixes=('','\x00'))
       .sort_index(axis=1).bfill(axis=1)[df.columns])

这里的想法是 left-merge 并通过对列进行排序(我们使用 '\x00' 作为 df2 中列的后缀,因为它是具有最低 Unicode 值的字符),我们确保相同的列值彼此相邻。然后水平使用 bfill 来更新 df1 和来自 df2.

的值

示例:

假设你有 df1:

   C1 C2   C3  C4
0   1  a  1.0   0
1   1  b  NaN   1
2   2  b  NaN   2
3   2  b  NaN   3

df2

   C1 C2  C3
0   1  b   2
1   2  b   3

并且您想用 df2 中的值为每对 C1-C2 值对填充 df1 中的缺失值。然后

cols_to_be_matched = ['C1', 'C2']

以上所有代码都会产生以下输出(其中的值确实已按要求填写):

   C1 C2   C3  C4
0   1  a  1.0   0
1   1  b  2.0   1
2   2  b  3.0   2
3   2  b  3.0   3