我正在尝试合并两个数据帧并将左侧 df 中的 nan 替换为右侧 df,我可以使用下面的三行代码来完成,但我想知道是否有更好/更短的方法?
# Example data (my actual df is ~500k rows x 11 cols)
df1 = pd.DataFrame({'a': [1,2,3,4], 'b': [0,1,np.nan, 1], 'e': ['a', 1, 2,'b']})
df2 = pd.DataFrame({'a': [1,2,3,4], 'b': [np.nan, 1, 0, 1]})
# Merge the dataframes...
df = df1.merge(df2, on='a', how='left')
# Fillna in 'b' column of left df with right df...
df['b'] = df['b_x'].fillna(df['b_y'])
# Drop the columns no longer needed
df = df.drop(['b_x', 'b_y'], axis=1)
最佳答案
混淆合并的问题是两个数据帧都有一个“b”列,但左右版本在不匹配的地方有 NaN。您首先要避免从 merge
中获取不需要的多个“b”列“b_x”、“b_y”:
- 从 df1 中切出非共享列 'a','e'
- 执行
merge(df2, 'left')
,这将从右侧数据帧中获取 'b'(因为它仅存在于右侧 df 中) - 最后做
df1.update(...)
,这将使用df1['b']
更新从 df2 获取的“b”列中的 NaN
解决方法:
df1.update(df1[['a', 'e']].merge(df2, 'left'))
df1
a b e
0 1 0.0 a
1 2 1.0 1
2 3 0.0 2
3 4 1.0 b
注意:因为我使用了 merge(..., how='left')
,所以我保留了调用数据帧的行顺序。如果我的 df1
的 a
值不按顺序
a b e
0 1 0.0 a
1 2 1.0 1
2 4 1.0 b
3 3 NaN 2
结果是
df1.update(df1[['a', 'e']].merge(df2, 'left'))
df1
a b e
0 1 0.0 a
1 2 1.0 1
2 4 1.0 b
3 3 0.0 2
这是预期的。
进一步...
如果你想在可能涉及更多列的时候更明确
df1.update(df1.drop('b', 1).merge(df2, 'left', 'a'))
更进一步...
如果你不想更新
dataframe,我们可以使用combine_first
快速
df1.combine_first(df1[['a', 'e']].merge(df2, 'left'))
显式
df1.combine_first(df1.drop('b', 1).merge(df2, 'left', 'a'))
更进一步!...
'left'
merge
可能保留顺序但不是 索引。这是极端保守的方法:
df3 = df1.drop('b', 1).merge(df2, 'left', on='a').set_index(df1.index)
df1.combine_first(df3)
关于python - Pandas 将数据框与共享列合并,左右填充,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56842140/