您好,我有一个数据框,例如:
species family Events groups
1 SP1 A 10,22 G1
2 SP1 B 7 G2
3 SP1 C,D 4,5,6,1,3 G3,G4,G5,G6
4 SP2 A 22,10 G1
5 SP2 D,C 6,5,4,3,1 G4,G6,G5,G3
6 SP3 C 4,5,3,6,1 G3,G6,G5
7 SP3 E 7 G2
8 SP3 A 10 G1
9 SP4 C 7,22 G12
并且我想简单地为每一列中至少有一个重复元素的每一行合并行(species
除外)。
例如我将合并行:
species family Events groups
SP1 A 10,22 G1
species family Events groups
SP2 A 22,10 G1
species family Events groups
SP3 A 10 G1
进入
species family Events groups
SP1,SP2,SP3 A 10,22 G1
所以,如果我对每一行都做同样的事情,我应该得到一个预期的输出:
species family Events groups
SP1,SP2,SP3 A 10,22 G1
SP1,SP3 B,E 7 G2
SP1,SP2,SP3 C,D 1,3,4,5,6 G3,G4,G6,G5
SP4 C 7,22 G12
请注意,SP4 尚未与任何行合并,因为它的组不存在于任何其他行中。
有人有想法吗? 非常感谢您的帮助和时间
这是它可以帮助的 dic 格式的数据框:
{'species': {1: 'SP1', 2: 'SP1', 3: 'SP1', 4: 'SP2', 5: 'SP2', 6: 'SP3', 7: 'SP3', 8: 'SP3', 9: 'SP4'}, 'family': {1: 'A', 2: 'B', 3: 'C,D', 4: 'A', 5: 'D,C', 6: 'C', 7: 'E', 8: 'A', 9: 'C'}, 'Events': {1: '10,22', 2: '7', 3: '4,5,6,1,3', 4: '22,10', 5: '6,5,4,3,1', 6: '4,5,3,6,1', 7: '7', 8: '10', 9: '7,22'}, 'groups': {1: 'G1', 2: 'G2', 3: 'G3,G4,G5,G6', 4: 'G1', 5: 'G4,G6,G5,G3', 6: 'G3,G6,G5', 7: 'G2', 8: 'G1', 9: 'G12'}}
答案 0 :(得分:1)
这里的技巧是用逗号分割单元格,将它们作为集合处理,最后将它们连接回来。这些确实是不可向量化的操作,但它会导致使用 apply
的(相当)简单的代码。
我会首先为每一行计算一个包含组:
g = df['groups'].apply(lambda x: set(x.split(','))) # explode into sets
# keep the larger set from g containing the current one and make it back a string
g2 = g.apply(lambda s: ','.join(sorted(
g[g.apply(lambda x: x.issuperset(s))].max())))
使用示例,它给出:
1 G1
2 G2
3 G3,G4,G5,G6
4 G1
5 G3,G4,G5,G6
6 G3,G4,G5,G6
7 G2
8 G1
9 G12
Name: groups, dtype: object
我们现在可以使用它来 groupby
数据框并使用 set 技巧聚合组:
resul = df[['species', 'family', 'Events']].groupby(g2).agg(
lambda x: ','.join(sorted(set((i for j in x for i in j.split(',')))))
).reset_index().reindex(df.columns)
我们得到了预期的结果:
species family Events groups
0 SP1,SP2,SP3 A 10,22 G1
1 SP4 C 22,7 G12
2 SP1,SP3 B,E 7 G2
3 SP1,SP2,SP3 C,D 1,3,4,5,6 G3,G4,G5,G6