数据框中所有独特的列组合。

问题描述 投票:1回答:2

谢谢你的阅读。

我正在尝试创建 数据框中所有可能的列的唯一组合。. 因此,有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)

基本上 "梳子 "迭代器从第一列(A)开始 第二个迭代器 "梳子2 "从第二列(B)开始,创建AB,然后继续前进,直到所有的A组合被创建。然后,当梳子到B时,梳子2从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选项,因为它可以更多的控制我们想要的组合数量,而且可能它并不那么难以映射。有什么想法吗?

先谢谢你。

为了说明问题,我忘了说,行是字符串。这里是真正的列的片段。

retired     nationality     region
   1         Portugal       Lisbon

因此,创建所有的组合 只是这三个例子,将是:

retired  nationality  region  retired + nationality   retired + region   (..)
   1      Portugal    Lisbon      1 + Portugal           1 + Lisbon
python pandas combinations itertools
2个回答
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  

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 与你想要的值,并将所有结果收集到一个列表中,然后再制作数据帧。

© www.soinside.com 2019 - 2024. All rights reserved.