python - 在 pandas 数据框中动态创建所有列组合
问题描述
我有一个df
包含列和字符串值的数据框。我的目标是创建一个数据框final_df
,其列代表df
' 列的所有可能组合,包括它们的值(理想情况下由_
[不在示例代码中] 分隔)。
示例代码:
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:])
是否有一种 Pythonic 方法可以根据列数动态创建这样的数据框?final_df
解决方案
我想到了一个解决方案,但是......列名不会改变。
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
推荐阅读
- coq - Coq:将使用 CPS 风格的 Ltac 策略移植到 ML 策略(OCaml 插件)
- ruby-on-rails - Rails 中的 FOREIGN KEY ON DELETE SET NULL
- php - 内连接 MySQL 图像显示
- python - 子进程python读取输出
- node.js - 如何正确使用带 passport_ldapauth 的会话?
- elasticsearch - Mapper_parsing_exception :压缩器检测只能在某些 xcontent 字节或压缩的 xcontent 字节上调用
- python - 使用请求获取请求未返回主机标头
- jquery - 如何在 ASP.NET MVC 5 项目中使用 jquery-validation-unobtrusive 验证文件的大小?
- c# - 如何使用 AuthenticationMiddleware 和注入应用程序设置
- ios - 在自定义迁移策略中传递给模型迁移函数时,Core Data 实体中的 Int16 支持的枚举属性似乎具有不正确的值