Python 从部分分类列获取值\u计数

Python 从部分分类列获取值\u计数,python,pandas,Python,Pandas,我希望尝试使用pandas(v0.23.4)从分类列(具体来说,包含月份信息)中获取值\u计数。当所有类别都存在时,此功能正常工作: import calendar import random import pandas as pd random.seed(1) month_names = calendar.month_name[1:] month_names += month_names df1 = pd.DataFrame({ 'Month': month_names,

我希望尝试使用
pandas
(v0.23.4)从
分类列(具体来说,包含月份信息)中获取
值\u计数。当所有类别都存在时,此功能正常工作:

import calendar
import random

import pandas as pd

random.seed(1)

month_names = calendar.month_name[1:]
month_names += month_names

df1 = pd.DataFrame({
    'Month': month_names,
    'Flag': [random.choice([True, False]) for _ in month_names]
})

df1['Month'] = pd.Categorical(
    df1['Month'], categories=calendar.month_name[1:], ordered=True
)
print(df1.groupby('Month')['Flag'].value_counts())
按预期打印:

Month      Flag 
January    False    2
February   True     2
March      False    2
April      True     2
May        True     2
June       False    2
July       False    1
           True     1
August     False    1
           True     1
September  False    2
October    True     2
November   False    1
           True     1
December   False    2
Name: Flag, dtype: int64
但是,如果我们的
'Month'
列未包含所有可能的类别,
pandas
将抛出一个
ValueError
。例如:

month_names = ['January', 'February', 'March']
month_names += month_names

df2 = pd.DataFrame({
    'Month': month_names,
    'Flag': [random.choice([True, False]) for _ in month_names]
})

df2['Month'] = pd.Categorical(
    df2['Month'], categories=calendar.month_name[1:], ordered=True
)
print(df2.groupby('Month')['Flag'].value_counts())
提出:

ValueError: operands could not be broadcast together with shape (12,) (3,)

我们有没有办法从部分数据中获得正确的
值\u计数
结果?理想情况下,这将保留完整的类别集,但即使没有也将是一个开始。

如果您只想要观察到的类别,您可以使用
观察到的
-关键字:

print(df2.groupby('Month', observed=True)['Flag'].value_counts())
#Month     Flag 
#January   False    1
#          True     1
#February  True     2
#March     False    2
#Name: Flag, dtype: int64
要获取groupby中的所有值,可以使用一种变通方法,使用
交叉表
,然后使用所有类别。老实说,我不知道为什么原始的
GroupBy
会给出
value\u counts()
的错误(它对其他方法很有效),但在使用将
标志
-列设置为多索引后,这种方法可以工作:

(pd.crosstab(df2['Month'], df2['Flag'])
.reindex(df2['Month'].cat.categories.tolist(), fill_value=0)
.stack())
#Month      Flag 
#January    False    1.0
#           True     1.0
#February   False    0.0
#           True     2.0
#March      False    2.0
#           True     0.0
#April      False    0.0
#           True     0.0
#May        False    0.0
#           True     0.0
#June       False    0.0
#           True     0.0
#July       False    0.0
#           True     0.0
#August     False    0.0
#           True     0.0
#September  False    0.0
#           True     0.0
#October    False    0.0
#           True     0.0
#November   False    0.0
#           True     0.0
#December   False    0.0
#           True     0.0

这太完美了,非常感谢。我觉得奇怪的是,
observed=False
基本上是以这种方式出现故障的,但在我的情况下,
observed=True
应该足够了。