如何将许多列汇总成唯一的组合
How to summarize many columns into unique combinations
我有一个数据框,行中有设备列表,列中有许多需要设备结构的实验:
equipment exp-1 exp-2 ... exp-n
equip-1 T F T
. . . .
equip-n T F F
设备名称是字符串,布尔值定义给定实验是否需要该设备。我试图将每个实验的所有不同设备要求压缩到通用列表中。最终目标是生成可用于该集合中多个实验的设备列表。
我通过执行以下步骤设法实现了这一目标:
- 转置数据帧并将所有布尔字段连接在一起
- 获取这些串联值的所有唯一实例
- 使用 .loc 遍历数据框并将合并后的 ID 分配给每一行
- 删除重复项。
最终结果如下所示:
experiment equip-1 ... equip-n equip-concat combo
exp-1 T T T...T 0
exp-2 F F F...F 1
exp-3 T F T...F 2
然后我能够再次转置它并将其粘贴回原始数据框中。所以我现在为每个组合都有一个布尔值列,显示一件设备是否属于它。
equipment exp-1 exp-2 ... exp-n combo-1 ...combo-n
equip-1 T F T T F
. . . .
equip-n T F F F F
我还需要获取属于给定组合的所有实验的列表:
combo 1: exp-1, exp-2, exp4
combo 2: exp-3, exp-5
...
我通过对组合数据进行分组并打印出来实现了这一点。
是否有更简洁的方法从初始实验定义中获得我需要的结果?我的方法好像有点笨
编辑:
初始步骤的代码,一件事是我的初始实现将布尔值视为字符串。在这种情况下,配置是我试图提出的组合设备集。
dfexp = df.copy().set_index("equipment").transpose()
dfexpagg = dftests.agg("".join, axis=1)
dfexpagg.name = "Agg Gear"
dfexp["aggregated_gear"] = dfexpagg
unique_configs = dfexp["aggregated_gear"].unique()
for x, config in enumerate(unique_configs):
dfexp.loc[dfexp["aggregated_gear"] == config, "Config"] = str(x)
dfconfigs = dfexp.set_index("Config"), drop=True).drop("aggregated_gear", axis=1).drop_duplicates().transpose()
我在 excel 中做了一个突出显示的示例,希望这有助于阐明最终目标。配置是我要生成的列。
我认为你不需要将它贴回原始数据框。
最终目标就像你描述的那样。所以formatting-wise,最接近和最清晰的是使用dictionary/JSON结构。例如,
# A map of equip_concat to list of experiment names
combo_map = {
'TFFTFTT...' : ['exp_1', 'exp_4', ...]
},
'TFTFTFT...' : ...
}
所以只需遍历你的数据框并打印你的字典。
combo_map = {}
for index, row in df.iterrows():
equip_concat = row['equip-concat']
if equip_concat not in combo_map:
combo_map[equip_concat] = []
combo_map[equip_concat].append(row['experiment'])
print(combo_map)
遍历列:
df = pd.DataFrame([['T', 'F', 'T','T'], ['F', 'F', 'T','F'], ['F', 'F','T','F']], index = ['eq1', 'eq2', 'eq3'], columns = ['ex1', 'ex2', 'ex3', 'ex4'])
output = {}
for i, col in enumerate(df.columns):
temp = df.index[df[col] == 'T'].tolist()
if temp not in output.values():
output[f'combo-{i}'] = temp
输出:
{'combo-0': ['eq1'], 'combo-1': [], 'combo-2': ['eq1', 'eq2', 'eq3']}
我有一个数据框,行中有设备列表,列中有许多需要设备结构的实验:
equipment exp-1 exp-2 ... exp-n
equip-1 T F T
. . . .
equip-n T F F
设备名称是字符串,布尔值定义给定实验是否需要该设备。我试图将每个实验的所有不同设备要求压缩到通用列表中。最终目标是生成可用于该集合中多个实验的设备列表。
我通过执行以下步骤设法实现了这一目标:
- 转置数据帧并将所有布尔字段连接在一起
- 获取这些串联值的所有唯一实例
- 使用 .loc 遍历数据框并将合并后的 ID 分配给每一行
- 删除重复项。
最终结果如下所示:
experiment equip-1 ... equip-n equip-concat combo
exp-1 T T T...T 0
exp-2 F F F...F 1
exp-3 T F T...F 2
然后我能够再次转置它并将其粘贴回原始数据框中。所以我现在为每个组合都有一个布尔值列,显示一件设备是否属于它。
equipment exp-1 exp-2 ... exp-n combo-1 ...combo-n
equip-1 T F T T F
. . . .
equip-n T F F F F
我还需要获取属于给定组合的所有实验的列表:
combo 1: exp-1, exp-2, exp4
combo 2: exp-3, exp-5
...
我通过对组合数据进行分组并打印出来实现了这一点。
是否有更简洁的方法从初始实验定义中获得我需要的结果?我的方法好像有点笨
编辑: 初始步骤的代码,一件事是我的初始实现将布尔值视为字符串。在这种情况下,配置是我试图提出的组合设备集。
dfexp = df.copy().set_index("equipment").transpose()
dfexpagg = dftests.agg("".join, axis=1)
dfexpagg.name = "Agg Gear"
dfexp["aggregated_gear"] = dfexpagg
unique_configs = dfexp["aggregated_gear"].unique()
for x, config in enumerate(unique_configs):
dfexp.loc[dfexp["aggregated_gear"] == config, "Config"] = str(x)
dfconfigs = dfexp.set_index("Config"), drop=True).drop("aggregated_gear", axis=1).drop_duplicates().transpose()
我在 excel 中做了一个突出显示的示例,希望这有助于阐明最终目标。配置是我要生成的列。
我认为你不需要将它贴回原始数据框。
最终目标就像你描述的那样。所以formatting-wise,最接近和最清晰的是使用dictionary/JSON结构。例如,
# A map of equip_concat to list of experiment names
combo_map = {
'TFFTFTT...' : ['exp_1', 'exp_4', ...]
},
'TFTFTFT...' : ...
}
所以只需遍历你的数据框并打印你的字典。
combo_map = {}
for index, row in df.iterrows():
equip_concat = row['equip-concat']
if equip_concat not in combo_map:
combo_map[equip_concat] = []
combo_map[equip_concat].append(row['experiment'])
print(combo_map)
遍历列:
df = pd.DataFrame([['T', 'F', 'T','T'], ['F', 'F', 'T','F'], ['F', 'F','T','F']], index = ['eq1', 'eq2', 'eq3'], columns = ['ex1', 'ex2', 'ex3', 'ex4'])
output = {}
for i, col in enumerate(df.columns):
temp = df.index[df[col] == 'T'].tolist()
if temp not in output.values():
output[f'combo-{i}'] = temp
输出:
{'combo-0': ['eq1'], 'combo-1': [], 'combo-2': ['eq1', 'eq2', 'eq3']}