应用pandas的groupby函数对每个索引进行分组

3

我有一个数据框,以人名作为索引(可以有多个条目),并且有两列“X”和“Y”。列“X”和“Y”可以是A-C之间的任何字母。

例如:

df = pd.DataFrame({'X' : ['A', 'B', 'A', 'C'], 'Y' : ['B', 'A', 'A', 'C']},index = ['Bob','Bob','John','Mike'])

对于每个人(即索引),我想获得列“X”和“Y”的每个唯一组合的出现次数(例如-对于Bob,我有1个('A','B')的计数和1个('B','A')的计数)。

当我执行以下操作时:

df.loc['Bob'].groupby(['X','Y']).size() 

我能为Bob获得正确的结果。如何在不使用循环的情况下对每个人进行计算?理想情况下,我希望获得一个数据框,以不同的人为索引,列“X”和“Y”的每个唯一组合作为列,并且出现在数据框中的次数作为值。
    ('A','A') ('A','B') ('A','C') ('B','A') ... ('C','C')
Bob     0         1         0         1             0
John    1         0         0         0             0
Mike    0         0         0         0             1
2个回答

4
使用get_dummiesgroupby进行操作。
pd.get_dummies(df.apply(tuple, 1)).groupby(level=0).sum()

      (A, A)  (A, B)  (B, A)  (C, C)
Bob        0       1       1       0
John       1       0       0       0
Mike       0       0       0       1

3

我认为你可以使用:

#convert columns X and Y to tuples
df['tup'] = list(zip(df.X, df.Y))

#get size and reshape
df1 = df.reset_index().groupby(['index','tup']).size().unstack(fill_value=0)
print (df1)
tup    (A, A)  (A, B)  (B, A)  (C, C)
index                                
Bob         0       1       1       0
John        1       0       0       0
Mike        0       0       0       1

#get all unique combination
from  itertools import product
comb = list(product(df.X.unique(), df.Y.unique()))
print (comb)
[('A', 'B'), ('A', 'A'), ('A', 'C'), ('B', 'B'), ('B', 'A'), 
 ('B', 'C'), ('C', 'B'), ('C', 'A'), ('C', 'C')]

#reindex columns by this combination
print (df1.reindex(columns=comb, fill_value=0))
tup    (A, B)  (A, A)  (A, C)  (B, B)  (B, A)  (B, C)  (C, B)  (C, A)  (C, C)
index                                                                        
Bob         1       0       0       0       1       0       0       0       0
John        0       1       0       0       0       0       0       0       0
Mike        0       0       0       0       0       0       0       0       1

为了更好地理解pandas,有没有使用pivot_table的方法来实现这个? - Eyal S.
使用 pivot_table 的解决方案是 df1 = df.reset_index().pivot_table(index='index', columns='tup', aggfunc='size', fill_value=0),而使用 crosstab 的解决方案是 df1 = pd.crosstab(df.index, df.tup) - jezrael

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