gpt4 book ai didi

python - 在 Pandas 中执行 "outer"连接时如何覆盖相同的列名?

转载 作者:行者123 更新时间:2023-11-28 17:26:08 31 4
gpt4 key购买 nike

我正在尝试合并/加入两个 csv,基于使用 Pandas 的唯一 city/country/state 列组合。但是,当我尝试使用外部联接执行此操作时,我会得到额外的列,而我更愿意让联接的“右侧”覆盖联接“左侧”的列。有什么建议吗?

这是我的尝试,有一个例子:

这些是我的 csv:

我的“左”csv 文件:

| city         | country | state |      pop |     lat |    long |
|--------------+---------+-------+----------+---------+---------|
| beijing | cn | 22 | 456 | 456 | 456 |
| buenos aires | ar | 7 | 13076300 | -34.613 | -58.377 |
| mexico city | mx | 9 | 123 | 123 | 123 |

我的“正确”csv 文件:

| city        | country | state |      pop |       lat |       long |
|-------------+---------+-------+----------+-----------+------------|
| adamsville | us | al | 4400 | 33.60575 | -86.97465 |
| alabaster | us | al | 32707 | 33.219442 | -86.823907 |
| beijing | cn | 22 | 11716620 | 39.907 | 116.397 |
| mexico city | mx | 9 | 12294193 | 19.428 | -99.128 |

我想要这个结果:

| city         | country | state |      pop |       lat |       long |
|--------------+---------+-------+----------+-----------+------------|
| adamsville | us | al | 4400 | 33.60575 | -86.97465 |
| alabaster | us | al | 32707 | 33.219442 | -86.823907 |
| beijing | cn | 22 | 11716620 | 39.907 | 116.397 |
| buenos aires | ar | 7 | 13076300 | -34.613 | -58.377 |
| mexico city | mx | 9 | 12294193 | 19.428 | -99.128 |

请注意,mexico citybeijing 被认为是匹配的,基于它们的 citycountry状态列。另请注意,在这些匹配行上,我“左”csv 中的每一列都被我“右”csv 中的匹配列覆盖。

所以这是我使用 Pandas 和数据框的尝试:

left = pd.read_csv('left.csv')
right = pd.read_csv('right.csv')

result = pd.merge(left, right, on=['city', 'country', 'state'], how='outer')

不幸的是,这是我的结果:

| city         | country | state |    pop_x |     lat_x |     long_x |    pop_y |     lat_y |     long_y |
|--------------+---------+-------+----------+-----------+------------+----------+-----------+------------|
| adamsville | us | al | 4400 | 33.60575 | -86.97465 | 4400 | 33.60575 | -86.97465 |
| alabaster | us | al | 32707 | 33.219442 | -86.823907 | 32707 | 33.219442 | -86.823907 |
| albertville | us | al | | 34.26313 | -86.21066 | | 34.26313 | -86.21066 |
| beijing | cn | 22 | 456 | 456 | 456 | 11716620 | 39.907 | 116.397 |
| buenos aires | ar | 7 | 13076300 | -34.613 | -58.377 | 13076300 | -34.613 | -58.377 |
| mexico city | mx | 9 | 123 | 123 | 123 | 12294193 | 19.428 | -99.128 |
| mumbai | in | 16 | 12691836 | 19.073 | 72.883 | 12691836 | 19.073 | 72.883 |
| shanghai | cn | 23 | 22315474 | 31.222 | 121.458 | 22315474 | 31.222 | 121.458 |

如上所示,未用于连接且具有相同名称的列被重命名为“左”数据框的 _x 后缀和 _y “正确”数据框的后缀。

是否有一种简单的方法可以使“右”数据框中的列在匹配时覆盖“左”数据框中的列?


虽然似乎已经有类似的问题,但我似乎仍然找不到答案。例如,我尝试实现基于 this question 的解决方案:

left = pd.read_csv('left.csv')
right = pd.read_csv('right.csv')
left = left.set_index(['city','country','state'])
right = right.set_index(['city','country','state'])
left.update(right)

update 仅执行左连接,因此生成的数据框仅具有与左数据框相同的行,因此它缺少像 adamsvillealabaster 这样的城市 以上。

最佳答案

由于两个数据框的列名相同,您可以将它们堆叠起来,然后执行 drop_duplicates 或 groupby

例如:

result = pd.concat([left, right]).reset_index()
result.drop_duplicates(['city','country','state'], keep='first', inplace=True)

或:

df_stacked = pd.concat([left, right]).reset_index()
result = df_stacked.groupby(['city','country','state']).first()

首先调用将从“左”df 获取“右”df 的值,因为我们将“左”df 堆叠在“右”df 之上并重置索引

如果您不想只获取第一条或最后一条记录,则使用 groupby 将允许您对聚合记录执行更复杂的选择。

编辑:

刚刚意识到您希望“右”df 覆盖“左”df,在这种情况下...

df_stacked = pd.concat([right, left]).reset_index()
result = df_stacked.groupby(['city','country','state']).first()

此方法仅在“左”和“右”数据框不包含重复记录时才有效。


郑重声明,要获得上述示例中的 csv 解决方案,我们可以执行以下操作:

result = result.reset_index()
# sort our descending population, and if populations are equal (or NaN), sort by ascending city name
result = result.sort_values(['pop', 'city'], ascending=[False, True])
result.drop('index', axis=1, inplace=True)
result.to_csv('result.csv', index=False)

关于python - 在 Pandas 中执行 "outer"连接时如何覆盖相同的列名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38908600/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com