Python中按link条件分组后统计category全类别计数的问题
问题与解决方案
需求说明
给定如下数据集:
| link | category | | ---- | -------- | | 1 | 0 | | 1 | 0 | | 1 | 1 | | 2 | 0 | | 3 | 1 | | 3 | 1 |
需要实现:
- 按
link分组,仅保留出现次数>1的link - 对每个分组的
category统计计数,必须显示所有category层级(即使该category在分组中未出现,计数显示为0)
期望输出格式如下:
| link | category counts | | ---- | --------------- | | 1 | 0 : 2 | | | 1 : 1 | | ---- | --------------- | | 3 | 0 : 0 | | | 1 : 2 |
测试数据生成代码
import pandas as pd df = pd.DataFrame({'link' : [1,1,1,2,3,3], 'category' : [0,0,1,0,1,1]})
现有尝试的问题
使用代码:
df.groupby('link')['category'].value_counts(sort=False)
得到的结果存在两个问题:
- 保留了出现次数仅1次的link2
- link3的category0未显示(缺失计数为0的行)
解决方案
步骤1:筛选有效link
先统计每个link的出现次数,过滤掉出现次数≤1的link:
# 统计每个link的出现次数 link_counts = df['link'].value_counts() # 筛选出现次数>1的link valid_links = link_counts[link_counts > 1].index # 过滤原数据框 filtered_df = df[df['link'].isin(valid_links)]
步骤2:统计所有category层级的计数
通过groupby+unstack补全缺失的category层级,自动填充计数为0:
# 分组统计,unstack后补全缺失category为0,再stack转回原结构 grouped_counts = filtered_df.groupby(['link', 'category']).size() \ .unstack(fill_value=0) \ .stack() # 转为DataFrame并重置索引 result_df = grouped_counts.reset_index(name='count')
运行后result_df的内容为:
link category count 0 1 0 2 1 1 1 1 2 3 0 0 3 3 1 2
步骤3:调整为期望的跨行显示格式
如果需要和示例一样的跨行合并link的显示效果,可以用pandas的style功能实现:
styled_table = result_df.style \ .set_table_styles([ # 给第一列添加右侧边框 {'selector': 'td:first-child', 'props': [('border-right', '1px solid #000')]}, # 在link3的行前添加分隔线 {'selector': 'tr:nth-child(3) td', 'props': [('border-top', '1px solid #000')]} ]) \ .hide(axis='index') # 显示表格 styled_table
完整可运行代码
import pandas as pd # 生成测试数据 df = pd.DataFrame({'link' : [1,1,1,2,3,3], 'category' : [0,0,1,0,1,1]}) # 筛选有效link link_counts = df['link'].value_counts() valid_links = link_counts[link_counts > 1].index filtered_df = df[df['link'].isin(valid_links)] # 统计所有category层级的计数 result_df = filtered_df.groupby(['link', 'category']).size() \ .unstack(fill_value=0) \ .stack() \ .reset_index(name='count') # 打印结果 print(result_df) # 生成跨行显示的样式表格(可选) styled_table = result_df.style \ .set_table_styles([ {'selector': 'td:first-child', 'props': [('border-right', '1px solid #000')]}, {'selector': 'tr:nth-child(3) td', 'props': [('border-top', '1px solid #000')]} ]) \ .hide(axis='index') styled_table
内容的提问来源于stack exchange,提问作者AngelMarcos
相关产品推荐
相关产品推荐

