数据框中的所有唯一列组合

时间:2020-05-13 08:25:09

标签: python pandas combinations itertools

感谢阅读。

我正在尝试创建数据框中列的所有可能的唯一组合。因此,在A,B,C和D列中,组合将为 AB,AC,AD,BC,BD,ABC,ABD

A   B   C   D   AB   AC   AD ...
1   1   3   2   2    4    3

为此,我创建了一个for循环:

for i, comb in enumerate(df_p.columns):
    for comb2 in df_p.columns[i:]:
        if (comb != comb2) & (comb not in comb2)):
            df_p[comb + ' + ' + comb2] = df_p[comb].astype('str') + ' + ' + df_p[comb2].astype("str")
            print(" comb: " + comb + " combines with comb2: " + comb2)

基本上,“ comb”迭代器在第一列(A)中开始,第二个迭代器“ comb2”在第二列(B)中开始,创建AB,然后继续直到创建所有A组合。然后,当梳子进入B时,梳子2从C开始,依此类推。 if条件阻止A + A以及A + BA之类的东西(当在df中使用更多列进行测试时,我遇到了一些错误)。

我现在的问题是关于反向重复项,例如当迭代器1在字母A上时创建“ ABD”(迭代器2将它与所有列组合在一起),而当迭代器1处在D和迭代器上时则创建“ DBA”两个都做所有组合。

在我的研究中,我还尝试使用itertools组合,例如:set(itertools.combinations(df_p.columns, 2))表示2的组合,以此类推,其他所有可能的组合都这样,但是我遇到了“映射”新创建的列组合的麻烦(例如AB)加上我原始df的列值(在这个范例中,这是A的列值+ B的列值)。

我更喜欢itertools选项,因为它可以更好地控制我们想要的组合数量,而且映射起来可能并不难。有什么想法吗?

先谢谢了。

---------------------------------- UPDATE ------------ -----------------------------

只是为了清除问题,我忘了提到行是字符串。这是真实列的片段:

retired     nationality     region
   1         Portugal       Lisbon

例如,仅创建这3个的所有组合将是:

retired  nationality  region  retired + nationality   retired + region   (..)
   1      Portugal    Lisbon      1 + Portugal           1 + Lisbon

2 个答案:

答案 0 :(得分:2)

IIUC,combinationsreduceSeries.add

from itertools import combinations
from functools import reduce

cols = df.columns.copy()
for i in range(2, len(cols) + 1):
    for names in combinations(cols, i):
        df[''.join(names)] = reduce(lambda cum_serie, new_serie_name: \
                                    cum_serie.add(df[new_serie_name]),
                                    names[1:],
                                    df[names[0]])


print(df)

输出

   A  B  C  D  AB  AC  AD  BC  BD  CD  ABC  ABD  ACD  BCD  ABCD
0  1  1  3  2   2   4   3   4   3   5    5    4    6    6     7

编辑

df = df.rename(columns=str).astype(str)
cols = df.columns.copy()
for i in range(2, len(cols) + 1):
    for names in combinations(cols, i):
        df[' + '.join(names)] = reduce(lambda cum_serie, new_serie_name: \
                                    cum_serie.str.cat(df[new_serie_name], ' + '),
                                    names[1:],
                                    df[names[0]])
print(df)

   A  B  C  D  A + B  A + C  A + D  B + C  B + D  C + D  A + B + C  A + B + D  \
0  1  1  3  2  1 + 1  1 + 3  1 + 2  1 + 3  1 + 2  3 + 2  1 + 1 + 3  1 + 1 + 2   

   A + C + D  B + C + D  A + B + C + D  
0  1 + 3 + 2  1 + 3 + 2  1 + 1 + 3 + 2  

答案 1 :(得分:2)

我认为使用combinations是正确的解决方法。

首先创建列组合列表:

col_combs = list(combinations(df.columns, 2))

然后要获取仅包含任何给定组合的那些列的df,请将组合元组转换为列表,然后将其传递给数据框。

cols = list(col_combs[0]
comb_df = `df[col_combs)]

下面是一个最小示例,说明如何为2列的每种组合存储单独的数据框:

col_combs = list(combinations(df.columns, 2))

comb_dfs = []

for cols in col_combs:
    temp = df[list(cols)].copy()
    comb_dfs.append(temp)

要使其适用于更大的列组合,您只需使用所需的值运行几个不同的combinations,然后在制作数据框之前将所有结果收集到一个列表中。

相关问题