【问题标题】:How to do data analysis (like counts, ucounts, frequency) with pandas?如何使用 pandas 进行数据分析(如计数、ucounts、频率)?
【发布时间】:2021-05-30 04:13:41
【问题描述】:

我有如下数据框:

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

预期输出如下:

更多详情:

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 来获得预期的结果?

相关截图:

【问题讨论】:

  • 看看agg函数
  • 我也试过代码 df.groupby(["cid","type"]).agg(counts=("userid", np.size), ucounts=("userid", "nunique")).reset_index() ,但不知道下一步该怎么做才能得到我想要的东西

标签: python pandas pandas-groupby data-analysis


【解决方案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 等)。

【讨论】:

    【解决方案2】:

    步骤:

    1. user_id 中提取id_numbers 并将它们转换为int type
    2. 使用groupbyagg 评估count/ucount / `频率。
    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}
    

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

    【讨论】:

    • 我试过你的代码,看起来我得到了错误,就像 df.assign code => KeyError: "[('userid', '')] not in index"
    • 但这就是你需要的吗?或不? @SilenceHe。
    • 顺便说一下,userid 有点像随机用户 cookie,所以它们不是像 {userid + number} 这样的常规字符串,所以可能df.userid.str.split('userid').str[1].astype(int) 不适合这种情况。
    • 是的,我就是这样,看来我的输出结果有问题,会更新这个问题的结果
    • 做了一些改动@SilenceHe
    猜你喜欢
    • 1970-01-01
    • 2018-09-25
    • 2013-06-11
    • 2020-02-07
    • 2017-04-03
    • 1970-01-01
    • 2014-06-10
    • 1970-01-01
    • 2011-05-12
    相关资源
    最近更新 更多