【问题标题】:Pandas merging dataframe with multiple column and tolerance熊猫合并具有多列和容差的数据框
【发布时间】:2020-07-29 17:42:58
【问题描述】:

我有 2 个数据框,我想使用 2 列作为键来合并它们并创建另一个合并的数据框。 这里,Column1 是 String,Columns2 是 float 数据类型。 我想在 column2 上设置 0.01 的容差,这样 dataframe1 的 (John, 1.12) 和 dataframe2 的 (John, 1.13) 应该在同一行。 我怎样才能做到这一点?

例如: 2个数据框:

df1 = pd.DataFrame({"Name":["John","Millon"], "MarketVal":[1.12,2.11], "Left_Product":["Sugar","Salt"]})
df2 = pd.DataFrame({"Name":["John","Rex"], "MarketVal":[1.13,3.11], "right_Product":["Sugar","Salt"]})

如果我这样做:

dfMerge = pd.merge(df1,df2,on=["Name","MarketVal"], how= "outer")

然后这将为“John”创建 2 个单独的行,因为 MarketVal 在两个数据框中都不同。但我想对此保持 0.01 的容忍度,以便它们位于同一行。

    Actual :->
     Name  MarketVal Left_Product right_Product
0    John       1.12        Sugar           NaN
1  Millon       2.11         Salt           NaN
2    John       1.13          NaN         Sugar
3     Rex       3.11          NaN          Salt

Expected :->

     Name  MarketVal Left_Product right_Product
0    John       1.12        Sugar           Sugar
1  Millon       2.11         Salt           NaN
2     Rex       3.11          NaN          Salt

【问题讨论】:

  • 那么,如果有多个左或右产品在同名 MarketVal 的通知范围内,会发生什么情况。例如 df2 中的另一个 John 1.13
  • 看看,merge-asof
  • 如果多行在公差范围内,它应该创建另一行。即如果 df2 的 3 行在 df1 的容差范围内,则应为每个组合创建 3 行
  • 另外,merge-asof 不适用于多列

标签: python pandas dataframe merge


【解决方案1】:

merge 仅在 'Name' 上,然后使用掩码仅保留在所需容差范围内的行。由于外部连接,如果任何“MarketVal”为空,我们也会保留一行。如果 'MarketVal' 来自外部合并中的正确 DataFrame,我们还需要更新它。

tol = 0.01
m = df1.merge(df2, on='Name', how='outer', suffixes=['', '_r'])
m = m[(m['MarketVal'] - m['MarketVal_r']).abs().le(tol)
      | m[['MarketVal', 'MarketVal_r']].isnull().any(1)]

#     Name  MarketVal Left_Product  MarketVal_r right_Product
#0    John       1.12        Sugar         1.13         Sugar
#1  Millon       2.11         Salt          NaN           NaN
#2     Rex        NaN          NaN         3.11          Sal

m['MarketVal'] = m['MarketVal'].fillna(m['MarketVal_r'])
m = m.drop(columns='MarketVal_r')

#     Name  MarketVal Left_Product right_Product
#0    John       1.12        Sugar         Sugar
#1  Millon       2.11         Salt           NaN
#2     Rex       3.11          NaN          Salt

df2 中匹配的多行的情况下,这将保留所有组合。在这里,我为 John 添加了另一行,其中包含 'Coffee' 应该与 df1 中的第一行匹配,以及一个不应该与任何内容匹配的行。

df1 = pd.DataFrame({'Name': ['John', 'Millon'], 
                    'MarketVal': [1.12, 2.11], 'Left_Product':['Sugar', 'Salt']})
df2 = pd.DataFrame({'Name': ['John', 'Rex', 'John', 'John'], 
                    'MarketVal': [1.13, 3.11, 1.125, 17], 
                    'right_Product': ['Sugar', 'Salt', 'coffee', 'bad_item']})

#... the above code
print(m)

     Name  MarketVal Left_Product right_Product
0    John       1.12        Sugar         Sugar
1    John       1.12        Sugar        Coffee
3  Millon       2.11         Salt           NaN
4     Rex       3.11          NaN          Salt

【讨论】:

  • 感谢您的帮助。我将检查真实数据并进行更新。
猜你喜欢
  • 2021-11-10
  • 2022-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多