Pandas - 按每个键的所有可能组合进行聚合

3

我是一个有用的助手,可以为您翻译内容。

我有一个Pandas DataFrame,我希望通过列A、B、C和D的组合来尽可能多地对数据进行分组。

假设它的形式如下:

      A   B   C   D   E   F   G        
0     Y   X   Y   Z   1   2   7
1     Y   X   Y   Z   3   4   8 
2     X   Y   U   V   1   1   1
3     X   Y   V   U   1   2   0
4     X   Z   Z   Z   1   8   1

首先,我尝试以更高的级别进行分组,所以我尝试按['A','B','C','D']进行分组。对于未重新分组的行,我会尝试较低的组合,例如['A','B','C'],['A','B','D']等。最后,我只是按['A'],然后按['B'],再按['C'],最后按['D']进行分组,而没有使用任何组合。此时,我已经使用每个可能的聚合键对数据进行了分组,这意味着A、B、C和D。
使用这种方法,期望的输出应该是:
      A   B   C   D           
0     Y   X   Y   Z    
1     X   Y     
2     X   

这些操作是否容易实现?

不太清楚您想要实现什么。请发布一些输入数据和期望的输出。您当前的输入数据只是一个空数据框。 - Plasma
是的,我修改了问题。 - Utopia
1个回答

2

我认为你需要先获取所有列值的组合:

df = pd.DataFrame({'A':[5,3,6,9,2,4],
                   'B':[4,5,4,5,5,4],
                   'C':[7,8,9,4,2,3],
                   'D':[1,3,5,7,1,0],
                   })

print (df)
   A  B  C  D
0  5  4  7  1
1  3  5  8  3
2  6  4  9  5
3  9  5  4  7
4  2  5  2  1
5  4  4  3  0

from  itertools import combinations
a = df.columns
comb = [j for i in range(len(a), 0, -1) for j in combinations(a,i)]
print (comb)
[('A', 'B', 'C', 'D'),
 ('A', 'B', 'C'), ('A', 'B', 'D'), ('A', 'C', 'D'), ('B', 'C', 'D'), 
 ('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'C'), ('B', 'D'), ('C', 'D'), 
('A',), ('B',), ('C',), ('D',)]

a = pd.concat([df.loc[:, x].sum(axis=1) for x in comb], axis=1)
print (a)
   0   1   2   3   4   5   6   7   8   9   10  11  12  13  14
0  17  16  10  13  12   9  12   6  11   5   8   5   4   7   1
1  19  16  11  14  16   8  11   6  13   8  11   3   5   8   3
2  24  19  15  20  18  10  15  11  13   9  14   6   4   9   5
3  25  18  21  20  16  14  13  16   9  12  11   9   5   4   7
4  10   9   8   5   8   7   4   3   7   6   3   2   5   2   1
5  11  11   8   7   7   8   7   4   7   4   3   4   4   3   0

可以使用 duplicatedconcat 方法通过获取所有重复值来寻找重复项,并使用 numpy.argmax 获取首个正确的 True 值:

print (pd.concat([df.duplicated(x, keep=False) for x in comb], axis=1))

      0      1      2      3      4      5      6      7      8      9   \
0   True   True   True   True   True   True   True   True   True   True   
1   True   True   True   True   True   True   True   True   True   True   
2  False  False  False  False  False   True  False  False  False  False   
3  False  False  False  False  False   True  False  False  False  False   
4  False  False  False  False  False  False  False  False  False  False   

      10    11     12     13     14  
0   True  True   True   True   True  
1   True  True   True   True   True  
2  False  True   True  False  False  
3  False  True   True  False  False  
4  False  True  False  False   True  

a = pd.concat([df.duplicated(x, keep=False) for x in comb], axis=1).values.argmax(axis=1)
print (a)
[ 0  0  5  5 11]

最后将该数组用作groupby的参数:

df = df.groupby(a).sum()
print (df)
    E  F   G
0   4  6  15
5   2  3   1
11  1  8   1

谢谢您的回复。我意识到我表达得不够清楚。我想使用groupBy函数按从高到低的所有可能组合来分组数据。 - Utopia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接