python - Pandas 将数据框与共享列合并,左右填充

标签 python pandas dataframe merge

我正在尝试合并两个数据帧并将左侧 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'),所以我保留了调用数据帧的行顺序。如果我的 df1a 值不按顺序

   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/

相关文章:

c++ - SIP4 中的共享指针和构建(原为 : Dynamic casting in SWIG/python? )

python - xlsxwriter Pandas 框架: to highlight rows if there are blank cells within a column

python - 获取向量最后 n 个周期的高点和低点

python - sep = '|' 在 pandas 数据框中无法正常运行

python - 如何重命名 pandas 数据框中的条目?

python - Pandas Dataframe 逐行填充新列

python - 奇怪的python列出了加法时的行为

python - 我可以更改给定 celery 任务的 ETA 参数吗?

python - Networkx - 允许重复的节点标签吗?

python-3.x - 如何在 Python 中查找表情符号的 unicode 平面