Pandas中Categorical类型过滤后value_counts返回0计数类别原因咨询
问题:过滤分类列后value_counts仍显示原全类别?
操作步骤与现象
1. 创建带分类列的DataFrame
df = pd.DataFrame({'years': [2015, 2016, 2017,2017, 2018, 2019, 2019, 2020]}) df['years'] = df['years'].astype('category') print(df.dtypes) # years category # dtype: object
2. 过滤得到子数据集
subset_years = [2015, 2016, 2017, 2018] subset_df = df[df['years'].isin(subset_years)] print(subset_df) # years # 0 2015 # 1 2016 # 2 2017 # 3 2017 # 4 2018
3. 方法结果差异
- 调用
unique():
subset_df.years.unique() # [2015, 2016, 2017, 2018] # Categories (4, int64): [2015, 2016, 2017, 2018]
- 调用
value_counts():
subset_df.years.value_counts() # 2015 1 # 2016 1 # 2017 2 # 2018 1 # 2019 0 # 2020 0 # Name: years, dtype: int64
疑问:已对years列进行过滤,为何value_counts()仍返回2019、2020且计数为0?这些类别不应在过滤后被移除吗?
原因解释
Pandas的分类类型(category)会保留原始数据集的完整类别集合,即便过滤出子数据集,分类列的类别体系不会自动收缩——这是分类类型的设计特性,用于维护统一的类别标准,方便后续的数据集合并、类别对比等操作。
unique()方法仅返回子数据集中实际存在的类别,因此不会显示2019、2020;value_counts()默认会遍历分类列的所有原始类别,对不存在的类别计数设为0。
解决方法
方法1:移除未使用的类别
对过滤后的分类列调用cat.remove_unused_categories(),重置为仅包含当前子数据集中存在的类别:
subset_df['years'] = subset_df['years'].cat.remove_unused_categories() subset_df.years.value_counts() # 2017 2 # 2015 1 # 2016 1 # 2018 1 # Name: years, dtype: int64
方法2:调整value_counts参数(Pandas >=1.3.0)
使用include_empty=False参数,让value_counts()仅统计子数据集中实际存在的类别:
subset_df.years.value_counts(include_empty=False) # 2017 2 # 2015 1 # 2016 1 # 2018 1 # Name: years, dtype: int64
内容的提问来源于stack exchange,提问作者floss
相关产品推荐
相关产品推荐

