如何执行Pandas外部合并,同时完全排除重复的条目?

pobjuy32  于 2022-12-09  发布在  其他
关注(0)|答案(1)|浏览(108)

假设我想外部合并2组大小不同的项(数据框),这些项没有 * 足够唯一 * 的键。
第一组:

  • 索引:1、2、3、4、5
  • 关键词:A、A、B、C、A
  • 产品:橙子,香蕉,煎饼,饼干,奥利奥

第二组:

  • 索引:1、2、3、4
  • 关键词:B、C、A、Z
  • 物料:缺货、有货、延期交货、缺货

所需结果(外部合并,索引顺序无关):

  • 第一行:缺货,B,煎饼
  • 第2行:库存、C、饼干
  • 第3行:延期交货,A,橙子

不匹配(仅右侧)(_O):

  • 图例:A、A
  • 项目:香蕉,奥利奥

不匹配(仅左侧)(_O):

  • 关键字:Z
  • 商品:脱销
  • 注意 *:不匹配的行将用于进一步合并。这是一个消除过程。以后的合并放宽了条件,但代价是降低了准确性。
    问题:

如果我使用外部合并,Pandas将找到每一个可能的组合,并创建重复(所有键A项目成为back-order,但我只需要一个,无论是)。
如果我删除了一个重复的记录,drop会在merge之后执行,所以我丢失了重复的记录,它们不能在以后的合并中使用。从技术上讲,我可以剖析删除的记录,并将它们重新添加到外部合并的 Dataframe 中,但性能和代码逻辑在规模(10 k+行,20+列)上变得非常糟糕。
我只能使用键,而不能使用索引,因为记录不遵循任何特定的顺序。
对于这个问题,蛮力解决方案本质上是有2个项目集。然后,使用嵌套循环迭代两个集合,找到一个匹配,然后从2个集合中删除匹配,以避免在下一次迭代中重复。这个解决方案的运行时间是O(N^2),是一个不可行的(需要20多个小时来运行)。
话虽如此,我应该如何处理这个问题?任何建议都是赞赏的。

fkaflof6

fkaflof61#

在两个数据框中创建一个带有groupby.cumcount的临时列,用作键之外的合并列。使用indicator=True创建一个列,以便以后选择三个部分(两者、仅右侧、仅左侧)。

res = (
    df1.assign(cc=lambda x: x.groupby('key').cumcount())
       .merge(df2.assign(cc=lambda x: x.groupby('key').cumcount()), 
              on=['key','cc'], how='outer', indicator=True)
)
print(res)
#   key  Items_x  cc       Items_y      _merge
# 0   A   Orange   0    Back-order        both
# 1   A   Banana   1           NaN   left_only
# 2   B  Pancake   0  Out-of-stock        both
# 3   C   Cookie   0      In-stock        both
# 4   A     Oreo   2           NaN   left_only
# 5   Z      NaN   0  Out-of-stock  right_only

然后,您可以根据具体情况使用_merge列进行选择,例如

print(res.loc[res['_merge'].eq('both')].drop(['cc','_merge'], axis=1))
#   key  Items_x       Items_y
# 0   A   Orange    Back-order
# 2   B  Pancake  Out-of-stock
# 3   C   Cookie      In-stock

相关问题