在pandas数据框中动态创建所有列组合

时间:2018-06-06 08:44:25

标签: python python-3.x loops combinatorics itertools

我有一个数据框AbstractCloudBigtableTableDoFn,其中包含列和字符串值。 我的目标是创建一个数据框df,其列代表final_df列的所有可能组合,包括它们的值(理想情况下用df分隔[不在示例代码中])

示例代码:

_

是否有一种Pythonic方法可以动态创建这样的import pandas as pd from itertools import combinations d = {'AAA': ["xzy", "gze"], 'BBB': ["abc", "hja"], 'CCC': ["dfg", "hza"], 'DDD': ["hij", "klm"], 'EEE': ["lal", "opa"]} df = pd.DataFrame(data=d) # two combinations cc = list(combinations(df.columns,2)) df_2 = pd.concat([df[c[0]] + df[c[1]] for c in cc], axis=1, keys=cc) df_2.columns = df_2.columns.map(''.join) # three attributes del cc cc = list(combinations(df.columns,3)) df_3 = pd.concat([df[c[0]] + df[c[1]] + df[c[2]] for c in cc], axis=1, keys=cc) df_3.columns = df_3.columns.map(''.join) # four attributes del cc cc = list(combinations(df.columns,4)) df_4 = pd.concat([df[c[0]] + df[c[1]] + df[c[2]] + df[c[3]] for c in cc], axis=1, keys=cc) df_4.columns = df_4.columns.map(''.join) # five attributes del cc cc = list(combinations(df.columns,5)) df_5 = pd.concat([df[c[0]] + df[c[1]] + df[c[2]] + df[c[3]] + df[c[4]] for c in cc], axis=1, keys=cc) df_5.columns = df_5.columns.map(''.join) # join dataframes dfs = [df, df_2, df_3, df_4, df_5] final_df = dfs[0].join(dfs[1:]) 数据框,具体取决于列数?

1 个答案:

答案 0 :(得分:1)

我想到了一个解决方案,但是......列名不会改变。

def combodf(dfx, x): 
    d = (['_'.join(i) for i in zip(*a)] for a in combinations(df.T.values.tolist(), x)) 
    return pd.DataFrame(d).T 

final_df = pd.concat([df, *(combodf(df, i) for i in range(2,6))], 1) 

但是看看你的"栏"结构,将它们作为价值观更有意义。所以这是一个解决方法,我们将列移动到最后一行。

import pandas as pd
from itertools import combinations

def combodf(dfx, x):
    d = [['_'.join(i) for i in zip(*a)] for a in combinations(df.T.values.tolist(), x)]
    return pd.DataFrame(d).T

d = {
'AAA': ["xzy", "gze"], 
'BBB': ["abc", "hja"], 
'CCC': ["dfg", "hza"], 
'DDD': ["hij", "klm"], 
'EEE': ["lal", "opa"]
}

df = pd.DataFrame(data=d)
df.loc[len(df)] = df.columns # insert columns last row
df = pd.concat([df, *(combodf(df, i) for i in range(2,6))], 1)
df.columns = df.tail(1).values[0] # make last row columns
df = df.drop(2) # drop last row

比较:

print((df == final_df).all().all()) # True
print((df.columns == final_df.columns).all()) # True