【问题标题】:Generating all the combinations of 7 columns in a dataframe and add the corresponding rows to generate new columns生成数据框中7列的所有组合并添加相应的行以生成新列
【发布时间】:2019-01-10 19:27:00
【问题描述】:

我有一个类似于下面的数据框:

Wave    A    B   C
340    77   70  15
341    80   73  15
342    83   76  16
343    86   78  17

我想生成包含现有列的所有可能组合的列。我在这里展示了 3 个列,但在我的实际数据中,我有 7 列,因此总共有 127 个组合。期望的输出如下:

Wave    A    B   C   AB   AC   AD   BC ... ABC
340    77   70  15   147  92   ...
341    80   73  15   153  95   ... 
342    83   76  16   159  99   ...

我实现了一个效率很低的版本,其中用户输入组合(AB、AC 等),并使用行的总和创建一个新的 col。对于 127 种组合,这似乎几乎不可能完成,尤其是带有描述性的 col 名称。

【问题讨论】:

    标签: python-3.x pandas dataframe combinations


    【解决方案1】:

    使用来自 itertools 的 chain + combinations 创建所有组合的列表,然后对相应的列求和:

    from itertools import combinations, chain
    
    cols = [*df.iloc[:,1:]]
    l = list(chain.from_iterable(combinations(cols, n+2) for n in range(len(cols))))
    #[('A', 'B'), ('A', 'C'), ('B', 'C'), ('A', 'B', 'C')]
    
    for items in l:
        df[''.join(items)] = df.loc[:, items].sum(1)
    
       Wave   A   B   C   AB   AC  BC  ABC
    0   340  77  70  15  147   92  85  162
    1   341  80  73  15  153   95  88  168
    2   342  83  76  16  159   99  92  175
    3   343  86  78  17  164  103  95  181
    

    【讨论】:

      【解决方案2】:

      您需要先获取所有combination,然后我们只需获取combination,然后我们需要创建映射dictSeries

      l=df.columns[1:].tolist()
      
      l1=[list(map(list, itertools.combinations(l, i))) for i in range(len(l) + 1)]
      
      d=[dict.fromkeys(y,''.join(y))for x in l1 for y in x ]
      
      maps=pd.Series(d).apply(pd.Series).stack()
      df.set_index('Wave',inplace=True)
      df=df.reindex(columns=maps.index.get_level_values(1))
      #here using reindex , get the order of your new df to the maps keys
      df.columns=maps.tolist()
      # here assign the new value to the column , since the order is same that why here I am assign it back 
      df.sum(level=0,axis=1)
      
      Out[303]: 
             A   B   C   AB   AC  BC  ABC
      Wave                               
      340   77  70  15  147   92  85  162
      341   80  73  15  153   95  88  168
      342   83  76  16  159   99  92  175
      343   86  78  17  164  103  95  181
      

      【讨论】:

      • 老实说,这真的很聪明:)
      • 我复制粘贴了上面的代码,但它只给了我每列两个并且不求和但使用相同的列值,例如AB = 77, AB = 70
      猜你喜欢
      • 2018-05-06
      • 2017-06-08
      • 2017-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多