【问题标题】:Pandas - Aggregate by each possible combination of keysPandas - 按每个可能的键组合聚合
【发布时间】:2018-02-20 09:26:09
【问题描述】:

我有一个 DataFrame Pandas,我想用 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   

这些操作可以轻松完成吗?

【问题讨论】:

  • 目前还不清楚你想要实现什么。请发布一些输入数据和所需的输出。您当前的输入数据只是一个空数据框
  • 是的。我修改了问题。

标签: python python-3.x pandas dataframe


【解决方案1】:

我认为您首先需要列值的所有组合:

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 获取第一个Trues:

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
猜你喜欢
  • 2014-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-26
  • 1970-01-01
  • 2013-02-03
  • 2018-04-04
相关资源
最近更新 更多