【问题标题】:All unique column combinations in a dataframe数据框中的所有唯一列组合
【发布时间】:2020-05-13 08:25:09
【问题描述】:

感谢阅读。

我正在尝试创建数据框中所有可能的唯一列组合。因此,具有 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 组合。然后,当comb 到B 时,comb2 从C 开始,以此类推。 if 条件阻止了 A + A 和 A + BA 之类的事情(我在 df 中使用更多列进行测试时遇到了一些错误)。

我现在的问题是关于反向重复,例如当迭代器一位于字母 A 时创建“ABD”(迭代器二将它与所有列组合)以及当迭代器一位于 D 和迭代器时创建“DBA”两个做所有的组合。

在我的研究中,我也尝试过使用 itertools 组合,如下所示:set(itertools.combinations(df_p.columns, 2)) 用于 2 的组合,以此类推用于其他所有可能的组合,但后来我在“映射”新创建的列组合时遇到了麻烦(比如AB) 与我的原始 df 的行值(在此示例中,这将是 A 的行值 + B 的行值)。

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

提前致谢。

----------------------更新------------ -----------------------------

为了清楚起见,我忘了提到行是字符串。这是真实列的sn-p:

retired     nationality     region
   1         Portugal       Lisbon

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

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

【问题讨论】:

    标签: python pandas combinations itertools


    【解决方案1】:

    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  
    

    【讨论】:

    • 对我来说问题有点不清楚,但我认为 OP 需要这个,+1
    • 感谢您的帮助。可能我的错误是没有提到这些行是字符串,所以不是在 A 列下面有 1,而是我会有名称。因此,A(“John”)和 B(“Lisbon”)之间的组合将是一个新列“A + B”,其行值为“John + Lisbon”。尝试您的解决方案后,我收到“必须是 str,而不是浮动”错误,指向“df[''.join(names)] 位
    • 不客气,也许我们需要将列名转换为str。也可能有str列和非str列的混合,我们可以从df=df.rename(columns=str).astype(str)开始,然后cols = df.columns.copy()...
    • 哇,太棒了!它似乎确实结合了提供的数据框中的每一列。仅针对格式问题,您将如何在组合变量及其各自的行之间添加“+”?就像列名是“variable1 + variable2”和行是“row1 + row2”,而不是variable1variable2?
    • 我认为您需要:df[' + '.join(names)] = reduce(lambda cum_serie, new_serie_name: \ cum_serie.str.cat(df[new_serie_name], ' + '), names[1:], df[names[0]])。这里类似于cum_serie.add(' + ').add(df[new_serie_name])
    【解决方案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,然后在制作数据框之前将所有结果收集到一个列表中。

    【讨论】:

    • 感谢您的回答 Peritract。在列表(col_combs)中创建组合后,我仍然无法创建一个包含所有组合及其各自值的新 df。抓住我在下面对 ansev 的回答发表的评论,原始数据框只有字符串值,因此将“A”与“B”组合将创建一个新列“A + B”,其行值为“A + B”。如果 A 列的行值为 John 和 Mary,B 的行值为 Lisbon 和 Porto,则“A + B”列的行将是“John + Lisbon”和“Mary + Porto”。
    猜你喜欢
    • 2019-09-09
    • 1970-01-01
    • 1970-01-01
    • 2018-08-08
    • 2018-11-24
    • 1970-01-01
    • 2022-10-07
    • 1970-01-01
    • 2020-07-11
    相关资源
    最近更新 更多