【问题标题】:Merge rows with common two common values | Python合并具有共同两个共同值的行 | Python
【发布时间】:2020-10-27 03:11:19
【问题描述】:

我一直在努力解决行间的简单合并问题。我有两个带有以下列值的熊猫数据框

df_a.columns.to_list()
['id','food','color','type','shape']

df_b.columns.to_list()
['id','food','smell','date']

我想看看两个 DataFrame 中是否有重复的食物以将它们合并到一个中

df_total = pd.concat([df_a, df_b], keys=['A', 'B'], ignore_index=False)
df_total = df_total.sort_values(by=['food'],ascending=True);
df_total['food'].value_counts().loc[lambda x : x>=2]

Out[1]
apple       2
cheese      2

据此,“APPLE”和“CHEESE”是重复的。打印连接表时,我们得到

id     food     color     type     shape     smell       date
-----------------------------------------------------------------
 1     apple     red      fruit    round      NaN         NaT
 1     apple     NaN       NaN      NaN      soft     2020-06-05
 2     cheese  yellow     dairy   squared     NaN         NaT
 2     cheese    NaN       NaN      NaN      soft     2020-06-07
 3     lemon    green     fruit    round      NaN         NaT

期望的输出:

id     food     color     type     shape     smell       date
-----------------------------------------------------------------
 1     apple     red      fruit    round     soft     2020-06-05
 2     cheese  yellow     dairy   squared    soft     2020-06-07
 3     lemon    green     fruit    round      NaN         NaT

我的尝试:

这次使用 pd.merge 在两个 DataFrame 中使用 .reset_index 重新定义 df_total

df_total = pd.merge(df_a.reset_index(),df_b.reset_index(), how = 'right/left/outer/inner')

如何我使用了“right”、“left”、“outer”、“inner”的值,但它以这样的方式合并它们,就好像我刚刚删除了其中一行一样或者根本没有价值。如何获得所需的输出?

【问题讨论】:

  • 请添加更多数据,因为您提供的数据似乎无法生成所需的输出。
  • @CeliusStingher 有更多数据,大约有 60 行。只是显示了一些行以使其简单。所有重复的行都遵循相同的模式,一行有“颜色”、“类型”和“形状”,但缺少“气味”和“日期”,另一行反之亦然。
  • 明白了,也许我的回答可以帮助你解决问题

标签: python pandas dataframe


【解决方案1】:

您可以利用 groupby 的第一个/最后一个功能。

在这种情况下:

df.groupby(['food']).last().reset_index()

输出

        1  0       2      3        4     5           6
0   apple  1     red  fruit    round  soft  2020-06-05
1  cheese  2  yellow  dairy  squared  soft  2020-06-07
2   lemon  3   green  fruit    round   NaN         NaT

【讨论】:

  • groupby + last 的不错组合 :) +1
  • 如果具有重复值的行不在一起,这是否也有效?
  • 一旦组合在一起,它们就会在一起。但是,您可能需要先应用排序以确保它们按您喜欢的顺序排列。
【解决方案2】:

鉴于您生成的输出,因为您提供的数据不完整,我将通过使用 .drop_duplicates() 来解决问题,通过利用其参数 subsetkeep 而之前使用 bfill() 小心缺失值:

desired_output = original_output.bfill().drop_duplicates('food',keep='first')

例如,从你不想要的输出开始:

original_df = pd.DataFrame({'food':['apple','apple','cheese','cheese','lemon'],
                           'color':['red',np.nan,'yellow',np.nan,'green'],
                           'type':['fruit',np.nan,'dairy',np.nan,'fruit'],
                           'shape':['round',np.nan,'squared',np.nan,'round'],
                           'smell':[np.nan,'soft',np.nan,'soft',np.nan],
                           'date':[np.nan,'2020-06-05',np.nan,'2020-06-07',np.nan]})

使用以下行:

desired_df = original_df.bfill().drop_duplicates('food',keep='first')

输出:

     food   color   type    shape smell        date
0   apple     red  fruit    round  soft  2020-06-05
2  cheese  yellow  dairy  squared  soft  2020-06-07
4   lemon   green  fruit    round   NaN         NaN

【讨论】:

  • 如果我的理解是正确的,.drop_duplicates(keep='first') 正在使用重复值的第一行并将其他重复行的值附加到它, 正确的?另外,这会使字母顺序变得无用吗?
  • drop_duplicates(keep='first') 只是删除 food 列重复的行,只保留第一个。通过之前使用bfill(),我们将NaN 值替换为其他值,对于每个food,字母顺序是必需的。否则,我们需要先groupby,然后使用bfill(),这是一个有效且一致的替代方案。
猜你喜欢
  • 1970-01-01
  • 2021-03-15
  • 1970-01-01
  • 2021-08-28
  • 1970-01-01
  • 2018-11-29
  • 1970-01-01
  • 2013-12-16
  • 1970-01-01
相关资源
最近更新 更多