【问题标题】:Best way to concat/merge list of pandas dataframes into one while preserving all values in a given column将熊猫数据框列表合并/合并为一个同时保留给定列中的所有值的最佳方法
【发布时间】:2021-12-14 02:46:21
【问题描述】:

我有一个如下的 pandas 数据框列表,并希望将它们合并/合并,以便共享列中的值在所有数据框之间是详尽的。最好的方法是什么?

DF 1:

Col1 Col2
BLAH1 A
BLAH2 Z

DF 2:

Col1 Col2 Col3
BLAH2 Z B
BLAH3 Q K

DF 3:

Col1 Col4
BLAH2 C
BLAH3 W

期望的结果

Col1 Col2 Col3 Col4
BLAH1 A NaN NaN
BLAH2 Z B C
BLAH3 Q K W

【问题讨论】:

标签: python pandas dataframe


【解决方案1】:

如果键是唯一的,在每个数据帧中,你可以先 concat 然后 groupby:

list_dfs = [df1, df2, df3]
pd.concat(list_dfs).groupby('Col1').first()

一般情况下,您可以将reducemerge 组合在一起:

from functools import reduce

# find common columns
commons = reduce(lambda x,y: set(x).intersection(set(y)), list_dfs)

reduce(lambda x,y: x.merge(y, on=commons), list_dfs)

【讨论】:

  • 您提供的两种情况都会处理数据帧之间的重复列吗?很抱歉没有首先提到这也是一种可能性 - 我已经更新了这个问题。
  • 无论哪种方式,您都需要先识别公共列。然后替换'Col1' 处的列表。查看更新的答案(第二种方法)
  • 如果 Col1 是我想要合并的常见的,但 col2 出现在列表中的多个数据框中,如何最好地处理?目前我使用 suffixes=('', '_y') 然后 df.drop(df.filter(regex='_y$').columns.tolist(),axis=1, inplace=True)
  • 这会很困难,你应该尝试一组样本数据,其中Col2 只在df2df3 中,然后问你想从中得到什么?
  • 我想要它与我在编辑问题中显示的完全一样。 Col2 应该取数据帧中的值(跨数据帧的值,如果重复列,将是相同的)
【解决方案2】:

让我们使用functools.reducepd.DataFrame.combine_first 和理解:

from functools import reduce
reduce(lambda x, y: x.combine_first(y), 
       (df.set_index('Col1') for df in [df1,df2,df3])).reset_index()

输出:

    Col1 Col2 Col3 Col4
0  BLAH1    A  NaN  NaN
1  BLAH2    Z    B    C
2  BLAH3    Q    K    W

给定输入数据框:

df1 = pd.DataFrame({'Col1':['BLAH1', 'BLAH2'],
                   'Col2':[*'AZ']})
df2 = pd.DataFrame({'Col1':['BLAH2', 'BLAH3'],
                   'Col2':[*'ZQ'],
                   'Col3':[*'BK']})
df3 = pd.DataFrame({'Col1':['BLAH2', 'BLAH3'],
                    'Col4':[*'CW']})

【讨论】:

    【解决方案3】:

    我们可以像这样使用reducemerge

    from functools import reduce
    
    reduce(lambda left, right: pd.merge(left, right, on=list(left.columns.intersection(right.columns)), how='outer'), [df1, df2, df3])
    

    这里reduce将两个参数的apply函数从左到右累加到iterable的项上,从而将iterable缩减为单个值。
    左侧参数left 是累积值,右侧参数right 是来自可迭代对象的更新值。

    这里的技巧是merge 从 DataFrames 的公共列列表中获得预期的结果。 @QuangHoang 做了类似的事情 并在我面前找到诀窍。

    输出:

        Col1    Col2    Col3    Col4
    0   BLAH1   A       NaN     NaN
    1   BLAH2   Z       B       C
    2   BLAH3   Q       K       W
    

    【讨论】:

      猜你喜欢
      • 2017-09-04
      • 2018-12-10
      • 1970-01-01
      • 1970-01-01
      • 2021-03-06
      • 2021-09-02
      • 2017-08-13
      • 2016-10-31
      • 2018-11-18
      相关资源
      最近更新 更多