Python 为每个索引应用groupby
我有一个以人名为索引的数据框(可以有多个条目)和两列“X”和“Y”。列“X”和“Y”可以是A-C之间的任何字母 例如:Python 为每个索引应用groupby,python,pandas,Python,Pandas,我有一个以人名为索引的数据框(可以有多个条目)和两列“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 = 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()
我为鲍勃得到了正确的结果。我怎样才能在没有al-oop的情况下为每个人做到这一点?
理想情况下,我会得到一个数据框,其中不同的人作为索引,列“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
我认为你可以使用:
#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
使用
get_dummies
和groupby
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
为了更好地理解熊猫,有没有一种方法可以用pivot\u table来实现这一点呢?
pivot\u table的解决方案是df1=df.reset\u index().pivot\u table(index='index',columns='tup',aggfunc='size',fill\u value=0)
和crosstab的解决方案是df1=pd.crosstab(df.index,df.tup)