如何使用pandas进行数据分析(例如计数、唯一值计数、频率)?

6

我有如下所示的DataFrame:

df = pd.DataFrame([
    ("i", 1, 'GlIrbixGsmCL'),
    ("i", 1, 'GlIrbixGsmCL'),
    ("i", 1, '3IMR1UteQA'),
    ("c", 1, 'GlIrbixGsmCL'),
    ("i", 2, 'GlIrbixGsmCL'),
], columns=['type', 'cid', 'userid'])

期望输出结果如下: expect output

更多细节请参考:

i_counts, c_counts      => df.groupby(["cid","type"]).size()
i_ucounts, c_ucounts    => df.groupby(["cid","type"])["userid"].nunique()
i_frequency,u_frequency => df.groupby(["cid","type"])["userid"].value_counts()

对我来说似乎有点复杂,如何使用pandas获取预期结果?

相关截图: screenshots


1
请查看agg函数。 - rpanai
我也尝试了代码 df.groupby(["cid","type"]).agg(counts=("userid", np.size), ucounts=("userid", "nunique")).reset_index(),但不知道如何继续以获得我期望的结果。 - Silence He
2个回答

1
这是我的处理方法:
aggfuncs= {
    'counts': ('userid', 'count'), 
    'ucounts': ('userid', 'nunique'),
    'frequency': ('userid', lambda S: S.value_counts().to_dict()),
}

output = df.groupby(['cid', 'type']).agg(**aggfuncs).unstack()
output.columns = output.columns.map(lambda tup: '_'.join(tup[::-1]))

输出:

     c_counts  i_counts  c_ucounts  i_ucounts          c_frequency                           i_frequency
cid
1         1.0       3.0        1.0        2.0  {'GlIrbixGsmCL': 1}  {'GlIrbixGsmCL': 2, '3IMR1UteQA': 1}
2         NaN       1.0        NaN        1.0                  NaN                   {'GlIrbixGsmCL': 1}

我认为这是你想要的核心。您需要进行一些修饰性修改,以使输出与您的示例完全相同(例如fillna等)。

0

步骤:

  1. user_id中提取id_numbers并将它们转换为int类型
  2. 使用groupbyagg来计算count/ucount / frequency
  3. 使用pivot重构表格。
  4. 如果需要,展开列并使用reset_index
df['userid'] = df.userid.str.extract(r'(\d+)').astype(int)
k = df.groupby(["type", 'cid']).agg(count=('userid', 'count'), ucount=(
    'userid', 'nunique'), frequency=('userid', lambda x: x.value_counts().to_dict())).reset_index()
k = k.pivot(index=[k.index, 'cid'], columns='type').fillna(0)

输出:

      count      ucount      frequency              
type      c    i      c    i         c             i
  cid                                               
0 1     1.0  0.0    1.0  0.0    {1: 1}             0
1 1     0.0  3.0    0.0  2.0         0  {1: 2, 2: 1}
2 2     0.0  1.0    0.0  1.0         0        {1: 1}

然后进行列转换:

k.columns = k.columns.map(lambda x: '_'.join(x[::-1]))

输出:

       c_count  i_count  c_ucount  i_ucount c_frequency   i_frequency
  cid                                                                
0 1        1.0      0.0       1.0       0.0      {1: 1}             0
1 1        0.0      3.0       0.0       2.0           0  {1: 2, 2: 1}
2 2        0.0      1.0       0.0       1.0           0        {1: 1}

根据您编辑后的问题更新的答案:

k = df.groupby(["type" , 'cid']).agg(count = ('userid' ,'count') , ucount = ('userid', 'nunique') , frequency=('userid', lambda x: x.value_counts().to_dict())).reset_index()
k = k.pivot(index=['cid'], columns ='type').fillna(0)

输出:

    count   ucount  frequency
type    c   i   c   i   c   i
cid                     
1   1.0 3.0 1.0 2.0 {'userid001': 1}    {'userid001': 2, 'userid002': 1}
2   0.0 1.0 0.0 1.0 0   {'userid001': 1}

注意:如果需要编码userid,请使用df.userid = df.userid.factorize()[0]


我尝试了你的代码,似乎出现了错误,与 df.assign 代码类似 => KeyError: "[('userid','<lambda>')] 不在索引中"。 - Silence He
但这是否是你需要的呢?@SilenceHe。 - Nk03
顺便提一下,userid 就像随机用户 cookie 一样,因此它们不是常规字符串,例如 {userid + 数字},所以也许 df.userid.str.split('userid').str[1].astype(int) 不适用于这种情况。 - Silence He
是的,这就是我想要的。看起来我的输出结果有些问题,我会为这个问题更新结果。 - Silence He
做了一些更改 @SilenceHe - Nk03
之前的输出结果有误,已经更新了问题并展示了正确的输出。行索引0和1应该合并到第1行而不是第2行,并且真实的用户ID字符串类似于“GlIrbixGsmCL”,用作cookie ID,这意味着它不能转换为int类型。 - Silence He

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