python - 使用另一个数据框替换数据框值,没有索引匹配
问题描述
我想使用另一个数据帧选择性地覆盖数据帧中的值,该数据帧使用的列不是任一数据帧的索引。我可以通过临时切换索引列来解决这个问题,但我觉得必须有更好/更有效的方法。在 SE 和其他地方搜索这里没有成果。
示例数据
请注意几个关键点:
- df2 的行数超过了所需的行数,不应使用这些额外的行
- 'B' 的值在两个 dfs 中的顺序不同
- 现有索引不匹配。我的问题的重点是不应该使用对现有索引的匹配。
代码:
df1 = pd.DataFrame({
'A':['lorem','ipsum','dolor','sit'],
'B':[1,2,3,4],
'C':[30,40,5000,6000]})
df2 = pd.DataFrame({
'B':[4,3,5,6],
'C':[60,50,70,80]})
df1:
A B C
0 lorem 1 30
1 ipsum 2 40
2 dolor 3 5000
3 sit 4 6000
df2:
B C
0 4 60
1 3 50
2 5 70
3 6 80
我想要的输出
A B C
0 lorem 1 30
1 ipsum 2 40
2 dolor 3 50
3 sit 4 60
我的非理想解决方案
# save indices and columns for both dfs, then re-index both
col_order1 = df1.columns
old_index1 = df1.index # not needed in my example, but needed in generalized case
df1.set_index('B', inplace=True)
col_order2 = df2.columns
old_index2 = df2.index
df2.set_index('B', inplace=True)
# value substitution based on the new indices
df1.loc[df1.index.isin(df2.index), 'C'] = df2['C']
# undo the index changes to df1 and df2
df1.reset_index(inplace=True)
df1 = df1[col_order1]
df1.index = old_index1
df2.reset_index(inplace=True)
df2 = df2[col_order2]
df2.index = old_index2
显然这是可行的,但我是 Pandas 的新手,我觉得我缺少一些内置方法的知识来做我所描述的事情。
我怎样才能在不改变这些索引的情况下达到预期的结果?
解决方案
我会合并和 combine_first()
newDF = df1.merge(df2,
left_on="B",
right_on="B",
how='left',
suffixes=["", "_df2"])
newDF["C"] = newDF["C_df2"].combine_first(newDF["C"]).apply(int)
print(newDF[["A","B","C"]])
A B C
0 lorem 1 30
1 ipsum 2 40
2 dolor 3 50
3 sit 4 60
笔记:
- 当您在连接的每一侧都有相同的列名时,指定后缀是可取的,只是为了便于阅读 - 我在左侧使用空后缀
- 我在那里使用了 .apply(int) ,因为合并会生成 NaN 值,其中来自 df1 的连接键在 df2 中不存在。如果我没记错的话,整数列中存在 NaN 会将列转换为浮点数。
推荐阅读
- javascript - 如何使用 webpack 3 缩小 CSS 样式
- android - 什么可能导致 getExternalFilesDir 从外部 SD 卡返回路径?
- java - 如何使用 Arrays.sort 输出
- c# - 为什么我的主键会减慢简单的 linq-to-sql 查询?
- remote-debugging - stm32f429 buildroot 远程调试
- python - 如何在 python 中将连续的时间段组合在一起?
- php - 从 cURL 返回 jpeg
- python - 在 Python ftplib 中列出名称中带有 UTF-8 字符的文件
- css - 如何使用 css flexbox 布局日历而不让内容扩展框?
- java - Hibernate Criteria API Inner Join 中的不同结果