如何计算包括零出现的分类值?

数据挖掘 Python 熊猫
2021-09-22 02:34:06

我想按月计算代码数量。这是我的示例数据框。

        id    month  code
0     sally    0  s_A
1     sally    0    s_B
2     sally    0   s_C
3     sally    0   s_D
4     sally    0    s_E
5     sally    0   s_A
6     sally    0    s_A
7     sally    0   s_B
8     sally    0   s_C
9     sally    0   s_A

我使用 count() 转换为这个系列。

df.groupby(['id', 'code', 'month']).m.count()

id      code   month  count
sally  s_A      0    12
                1    10
                2     3
                7    15

但是,我想包括零出现,像这样。

id      code   month  count
sally  s_A      0    12
                1    10
                2     3
                3    0
                4    0
                5    0
                6    0
                7    15
                8    0
                9    0
                10   0
                11   0
2个回答

根据您提供的简短示例 DataFrame,此代码块将包括所有月份。它基于使用 Series.reindex 方法并使用月份的附加值创建一个新的 MultiIndex:

import pandas as pd
# Load example data into DataFrame
df = pd.read_table("categorical_data.txt", delim_whitespace=True)

# Transform to a count
count = df.groupby(['id', 'code', 'month']).month.count()

# Re-create a new array of levels, now including all 12 months
levels = [count.index.levels[0].values, count.index.levels[1].values, range(12)]
new_index = pd.MultiIndex.from_product(levels, names=count.index.names)

# Reindex the count and fill empty values with zero (NaN by default)
count = count.reindex(new_index, fill_value=0)
print(count)

打印结果,我得到这样的结果(只显示 sally/s_A 的第一个条目):

id     code  month
sally  s_A   0        4
             1        0
             2        0
             3        0
             4        0
             5        0
             6        0
             7        0
             8        0
             9        0
             10       0
             11       0

您要做的正是该category类型的默认行为。

将您的月份值转换为声明所有月份的类型类别(它有一个有点奇怪的接口来创建一个分类类型)

df.month= dd.month.astype(pd.api.types.CategoricalDtype(categories=range(12)))
df.month.value_counts()

会给你:

id     code  month
sally  s_A   0        4
             1        0
             2        0
             3        0
             4        0
             5        0
             6        0
             7        0
             8        0
             9        0
             10       0
             11       0

obs:你你的栏目拥有该类别的所有对象,它有一个更简单的界面:df.month.astype('category').