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, A
和 eee, B
交叉处更新的 NaN
值
其他答案中缺少的一个重要信息是 combine_first
和 fillna
都在索引上匹配,因此您必须使索引在 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
我找不到 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, A
和 eee, B
NaN
值
其他答案中缺少的一个重要信息是 combine_first
和 fillna
都在索引上匹配,因此您必须使索引在 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