我有这种数据帧df:
User,C,G
111,ar,1
112,es,1
112,es,1
112,es,2
113,es,2
113,es,3
113,es,3
114,es,4
我想要输出的是:
G,nU,ar,es
1,2,1,1
2,2,0,2
3,1,0,1
4,1,0,1
基本上,对于每个G
,我会计算User
列中其中nU
的不同数量以及C
中字符串的出现次数。每个用户都有一个唯一的C
值。
例如,在G
数字1中我有两个用户(111和112),其中一个出现在'ar'中,一个出现在'es'中(无论是否有两个112出现,我只需要( 112,'es')单身情侣)。总结'ar'和'es'列应返回nU
列。到目前为止,我试过这个:
d = df.reset_index().groupby('G')['User'].nunique()
正确返回用户数但没有关于C
列的信息。
很抱歉这可能造成混乱。
答案 0 :(得分:3)
给定df
,
result = df.groupby(['G', 'User'])['C'].value_counts()
产量
G User
1 111 ar 1
112 es 2
2 112 es 1
113 es 1
3 113 es 2
4 114 es 1
dtype: int64
这会计算ar
和es
的每次出现次数。我们真的只想计算唯一出现次数,所以让我们将系列中的每个值设置为1:
result[:] = 1
以便result
看起来像
G User
1 111 ar 1
112 es 1
2 112 es 1
113 es 1
3 113 es 1
4 114 es 1
dtype: int64
现在,如果我们按照第一个和最后一个索引级别(G
值和C
值)进行分组,并对每个组求和,
result = result.groupby(level=['G',-1]).sum()
我们得到了
G
1 ar 1
es 1
2 es 2
3 es 1
4 es 1
dtype: int64
现在我们可以取消堆叠最后一个索引级别:
result = result.unstack()
获取
ar es
G
1 1 1
2 NaN 2
3 NaN 1
4 NaN 1
用零填充NaN:
result = result.fillna(0)
定义nU
列和行的总和:
result['nU'] = result.sum(axis=1)
并重新排序列:
result = result[['nU', 'ar', 'es']]
全部放在一起:
import pandas as pd
df = pd.read_csv('data')
result = df.groupby(['G', 'User'])['C'].value_counts()
result[:] = 1
result = result.groupby(level=['G',-1]).sum()
result = result.unstack()
result = result.fillna(0)
result['nU'] = result.sum(axis=1)
result = result[['nU', 'ar', 'es']]
产量
nU ar es
G
1 2 1 1
2 2 0 2
3 1 0 1
4 1 0 1