【问题标题】:How to generate all possible combinations of columns in a pandas dataframe with many columns?如何在具有许多列的熊猫数据框中生成所有可能的列组合?
【发布时间】:2019-11-17 05:32:59
【问题描述】:

我有以下数据框:

   A  B  C
0  1  3  3
1  1  9  4
2  4  6  3

我想创建这些列的所有可能的唯一组合不重复,这样我最终会得到一个包含以下数据的数据框:A、B、C、A+B、A+ C、B+C、A+B+C。 我不想以任何组合重复任何列,例如A+A+B+C 或 A+B+B+C.

我还希望数据框中的每一列都标有相关的变量名称(例如,对于 A + B 的组合,列名称应为“A_B”)

这是所需的数据帧:

   A  B  C  A_B  A_C  B_C  A_B_C
0  1  1  4    2    5    5      6
1  3  9  6   12    9   15     18
2  3  4  3    7    6    7     10

使用 itertools 只需 3 个变量,这相对容易,我使用了以下代码:

    import pandas as pd
    import itertools

    combos_2 = pd.DataFrame({'{}_{}'.format(a, b):
    df[a] + df[b] 
    for a, b in itertools.combinations(df.columns, 2)})

    combos_3 = pd.DataFrame({'{}_{}_{}'.format(a, b, c):
    df[a] + df[b] + df[c] 
    for a, b, c in itertools.combinations(df.columns, 3)})

    composites = pd.concat([df, combos_2, combos_3], axis=1)

但是,我不知道如何以 Python 方式扩展此代码,以解决具有更多列数的 DataFrame。有没有办法让下面的代码更 Pythonic 并扩展它以用于大量列?或者有没有更有效的方法来生成组合?

【问题讨论】:

    标签: python pandas itertools


    【解决方案1】:

    我们需要先根据列创建combination,然后创建数据框

    from itertools import combinations
    input = df.columns
    output = sum([list(map(list, combinations(input, i))) for i in range(len(input) + 1)], [])
    output
    Out[21]: [[], ['A'], ['B'], ['C'], ['A', 'B'], ['A', 'C'], ['B', 'C'], ['A', 'B', 'C']]
    df1=pd.DataFrame({'_'.join(x) : df[x].sum(axis=1 ) for x in output if x !=[]})
    df1
    Out[22]: 
       A  B  C  A_B  A_C  B_C  A_B_C
    0  1  3  3    4    4    6      7
    1  1  9  4   10    5   13     14
    2  4  6  3   10    7    9     13
    

    【讨论】:

      【解决方案2】:

      你已经很接近了:

      from itertools import chain, combinations
      
      # Need to realize the generator to make sure that we don't
      # read columns from the altered dataframe.
      combs = list(chain.from_iterable(combinations(d.columns, i)
                                       for i in range(2, len(d.columns) + 1)))
      for cols in combs:
          df['_'.join(cols)] = df.loc[:, cols].sum(axis=1)
      

      注意事项 - 如果您将列与 _ 组合在一起,而列名本身可以包含 _,那么您迟早会遇到列名冲突。

      【讨论】:

      • 感谢您回答我的问题,但这并没有提供所需的数据框。相反,它返回一个包含 26 列的数据框(它应该只有 7 列,如我在原始问题中显示的所需数据框中所示)。我的问题可能不够清楚,但我只想要原始列不重复的每个唯一组合(即不应该有任何列 A + A + B + C)。
      • 我编辑了我的问题以指定我只想要组合而不重复单个列。为混乱道歉!
      • 糟糕,对此感到抱歉 - 我忽略了对 list 的调用,认为由于迭代而不需要它。但我错过了生成器会在每次迭代中看到更改的数据帧。我已经编辑了答案。另一种方法是只创建一个新的数据框,而不是更改现有的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多