【问题标题】:Merging two DataFrames with conditionals to either update column or append row使用条件合并两个 DataFrame 以更新列或追加行
【发布时间】:2017-09-01 07:40:39
【问题描述】:

我有 2 个具有相同列的数据框。我想在一个键列上合并(或连接)这些数据帧,如果两者之间存在键匹配,它只会更新匹配行的单个列,否则它将行附加到第一个/旧数据帧。

示例伪代码:

for row in new_dataset:
if new_dataset['key'] == old_dataset['key']:
    old_dataset['last_seen'] = new_dataset['last_seen']
else:
    append row to old_dataset

示例输入:

DF1

Key       First_Seen Last_Seen Data  Data
Bigfoot   2015       2015      Blah  Blah
Loch_Ness 2016       2016      Blah  Blah
UFO       2016       2004      Blah  Blah

DF2

Key       First_Seen Last_Seen Data  Data
UFO       2017       2017      Blah  Blah
Tupac     2017       2017      Blah  Blah

期望的输出:

DF3

Key       First_Seen Last_Seen Data  Data
Bigfoot   2015       2015      Blah  Blah
Loch_Ness 2016       2016      Blah  Blah
UFO       2016       2017      Blah  Blah
Tupac     2017       2017      Blah  Blah

编辑:我尝试了几种方法,包括:将键作为索引加入,在键上进行右合并,显式调用列,然后向左合并以附加不匹配的值。我面临的问题是合并要么想要合并所有列,并创建一个完全重复的 df,要么当我显式调用列时,它不允许匹配数据框的 pandas 系列。当我规范化为在列调用上使用 2 系列时,我无法返回匹配合并的特定行等。

【问题讨论】:

  • pd.concat 然后drop_duplicate
  • 那没有正确更新first_seen和last_seen列,会有数据丢失
  • 欢迎来到 Stack Overflow,@itotallyforgot。对于那些希望为您提供答案以了解您已经尝试过的内容以及它如何无法正常工作的人来说,这可能会有所帮助。
  • @Degan 我已经用我尝试过的一些东西更新了它。
  • @Wen was correct! 几乎...不太... UFO 需要2016 2017 在其行中。

标签: python-3.x pandas


【解决方案1】:

新答案

df1.append(df2).pipe(
    lambda d: (
        lambda f: f('Key').assign(
            Last_Seen=f('Key', 'last').Last_Seen.values)
    )(d.drop_duplicates)
).reset_index(drop=True)

         Key  First_Seen  Last_Seen  Data Data.1
0    Bigfoot        2015       2015  Blah   Blah
1  Loch_Ness        2016       2016  Blah   Blah
2        UFO        2016       2017  Blah   Blah
3      Tupac        2017       2017  Blah   Blah

变体
lambdamerge

df1.merge(df2, 'outer', 'Key', suffixes=['', '_']).pipe(
    lambda d: d.fillna(
        d.filter(regex='_$').rename(columns=lambda x: x[:-1])
    ).assign(Last_Seen=d.Last_Seen_.fillna(d.Last_Seen))
)[df1.columns].astype(df1.dtypes)

         Key  First_Seen  Last_Seen  Data Data.1
0    Bigfoot        2015       2015  Blah   Blah
1  Loch_Ness        2016       2016  Blah   Blah
2        UFO        2016       2017  Blah   Blah
3      Tupac        2017       2017  Blah   Blah

旧答案

d1, d2 = df1.set_index('Key').align(df2.set_index('Key'))
d3 = d1.combine_first(d2)
d3.update(d2.Last_Seen)
d3 = d3.reset_index().astype(df1.dtypes)
d3

         Key  First_Seen  Last_Seen  Data Data.1
0    Bigfoot        2015       2015  Blah   Blah
1  Loch_Ness        2016       2016  Blah   Blah
2      Tupac        2017       2017  Blah   Blah
3        UFO        2016       2017  Blah   Blah

【讨论】:

  • 就是这样。理想情况下,我不想创建第三个数据帧,因为前两个数据帧本身已经相当大,但我已经对其进行了几次测试,它看起来工作得很好。谢谢!当我尝试使用 combine_first 时,我现在也可以看到哪里搞砸了。
  • 如果您有兴趣,我提供了不同的答案。
  • 我会用更大的数据集做一些比较测试,让你知道它们的表现
  • 我做了一些测试,它的基本要点是直观地反击您的第三个答案,即在内存中创建第三个数据帧以供使用,速度更快,内存占用更少。我虽然用变体重新标记 64gbs 内存很有趣,哈哈!可能我可以做一些优化来控制内存问题,但我还没有技能。我仍然想玩它,所以我可以准确地理解它发生了什么。同时,再次感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-15
  • 1970-01-01
  • 2018-09-27
  • 1970-01-01
  • 2018-05-22
  • 2016-01-17
  • 2016-10-24
相关资源
最近更新 更多