如何按 ID 分组并获取每个类别的计数

Posted

技术标签:

【中文标题】如何按 ID 分组并获取每个类别的计数【英文标题】:How to group by ID and get the count per each category 【发布时间】:2021-10-04 17:26:29 【问题描述】:

我又来了。

我有一个这样的 df

    id  c1  c2  c3
0   0   11  12  0
1   0   15  15  1
2   0   4   24  2
3   0   5   13  2
4   0   3   15  1
5   0   5   7   0
6   0   3   18  2
7   0   17  9   3
8   0   0   17  1
9   0   12  0   0
10  1   17  9   3
11  1   1   21  2
12  1   0   3   1
13  1   4   20  3
14  1   8   22  0
15  1   16  23  2
16  1   0   3   1
17  1   4   20  3
18  1   19  17  1
19  1   12  0   0

对于每个 ID,我想计算 c3 中的值(将它们视为类别),然后将值除以 id 的长度。

例如: ID = 0 有 10 个观察值,c3.0 中有 3 个,c3.1 中有 3 个,c3.2 中有 3 个,c3.3 中有 1 个 ID = 1 有 10 个观测值,c3.0 中有 2 个,c3.1 中有 3 个,c3.2 中有 2 个,c3.3 中有 3 个

我想得到这样的东西:

ID c3.0  c3.1  c3.2   c3.3
0   0.3   0.3   0.3    0.1
1   0.2   0.3   0.2    0.3

列名不相关

感谢您的帮助!

【问题讨论】:

【参考方案1】:

你可以使用crosstab

result = pd.crosstab(df.id, df.c3, normalize='index')

重命名列:

result.columns = [f'result.columns.name.label' for label in result.columns]


result.rename_axis(None)
 
   c3.0  c3.1  c3.2  c3.3
0   0.3   0.3   0.3   0.1
1   0.2   0.3   0.2   0.3

【讨论】:

这个也可以,但我更喜欢另一个【参考方案2】:

我们可以使用groupby value_countsnormalize=True 来计算每个“id”中“c3”的出现次数,该id 由组的总长度标准化。然后unstack 获取宽格式:

out = df.groupby('id')['c3'].value_counts(normalize=True).unstack()

out:

c3    0    1    2    3
id                    
0   0.3  0.3  0.3  0.1
1   0.2  0.3  0.2  0.3

使用add_prefix 进行一些清理以更新列标题,并使用reset_index 使id 成为列:

out = (
    df.groupby('id')['c3'].value_counts(normalize=True)
        .unstack()
        .rename_axis(columns=None)
        .add_prefix('c3.')
        .reset_index()
)

out:

   id  c3.0  c3.1  c3.2  c3.3
0   0   0.3   0.3   0.3   0.1
1   1   0.2   0.3   0.2   0.3

【讨论】:

谢谢!它有效,我非常感谢您在输出表中包含更改名称的代码!喜欢它!

以上是关于如何按 ID 分组并获取每个类别的计数的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 仅按日期分组并获取计数

按每个 id 分组并获取第一个日期

mysql按字段分组并获取每个分组按照某个字段排序的前三条

mysql 计数,然后按该计数分组

如何对每个表进行分组计数并按列打印? [复制]

每月每个类别的分组计数(当前月份与过去几个月的剩余时间)在 pandas 的单独列中