Pandas按月分组统计报错ValueError及数据处理问询
Pandas分组统计、透视报错及零值列移除解决方案
首先,先把你的数据集构造出来方便复现:
import pandas as pd data = { 'Date': ['2017-08-07', '2017-08-07', '2017-08-08', '2017-08-22', '2017-09-23', '2017-10-09', '2017-10-09', '2017-10-09', '2017-10-23', '2017-11-08'], 'inp': ['2.3.6', '2.3.6', '2.3.6', '2.5.9', '0.8.0', '2.3.6', '2.3.6', '2.3.6', '0.8.0', '6.2.6'], 'name': ['ABC', 'ABC', 'TAC', 'TTT', 'TAC', 'ABC', 'TAC', 'TAC', 'TAC', 'ABC'] } df = pd.DataFrame(data)
一、报错原因分析
你遇到的ValueError: No axis named 'inp',是因为在调用groupby或其他方法时错误地把axis参数设成了列名'inp'。记住:axis参数只能接受0(行方向)或1(列方向),分组指定列应该直接把列名放进列表传给groupby,而不是用axis参数。
二、分步实现需求
1. 按月分组统计'inp'和'name'的出现次数(得到df2)
首先要把日期转为datetime类型,提取月份名称,再按月份、inp、name分组计数:
# 转换日期格式并提取月份名称 df['Date'] = pd.to_datetime(df['Date']) df['Month'] = df['Date'].dt.month_name() # 得到类似"August"的月份名称 # 分组统计次数 df2 = df.groupby(['Month', 'inp', 'name']).size().reset_index(name='Count')
此时df2的结果如下:
| Month | inp | name | Count | |
|---|---|---|---|---|
| 0 | August | 2.3.6 | ABC | 2 |
| 1 | August | 2.3.6 | TAC | 1 |
| 2 | August | 2.5.9 | TTT | 1 |
| 3 | October | 0.8.0 | TAC | 1 |
| 4 | October | 2.3.6 | ABC | 1 |
| 5 | October | 2.3.6 | TAC | 2 |
| 6 | September | 0.8.0 | TAC | 1 |
| 7 | November | 6.2.6 | ABC | 1 |
2. 透视得到df3
我们先把inp和name合并成一个组合列,再透视成“月份为行,组合列为列”的格式,空值用0填充:
# 创建inp+name的组合列 df2['inp_name'] = df2['inp'] + '_' + df2['name'] # 透视并填充空值 df3 = df2.pivot(index='Month', columns='inp_name', values='Count').fillna(0).astype(int)
df3的结果:
| Month | 2.3.6_ABC | 2.3.6_TAC | 2.5.9_TTT | 0.8.0_TAC | 6.2.6_ABC |
|---|---|---|---|---|---|
| August | 2 | 1 | 1 | 0 | 0 |
| October | 1 | 2 | 0 | 1 | 0 |
| September | 0 | 0 | 0 | 1 | 0 |
| November | 0 | 0 | 0 | 0 | 1 |
3. 移除零值数量超过2个的列
计算每列的零值个数,筛选出零值≤2的列:
# 统计每列的零值数量 zero_counts = df3.eq(0).sum(axis=0) # 保留零值数量≤2的列 df_final = df3.loc[:, zero_counts <= 2]
最终df_final会保留2.3.6_ABC、2.3.6_TAC、0.8.0_TAC这三列(它们的零值数分别是2、2、2),而零值数为3的2.5.9_TTT和6.2.6_ABC会被移除。
完整代码
import pandas as pd # 构造数据集 data = { 'Date': ['2017-08-07', '2017-08-07', '2017-08-08', '2017-08-22', '2017-09-23', '2017-10-09', '2017-10-09', '2017-10-09', '2017-10-23', '2017-11-08'], 'inp': ['2.3.6', '2.3.6', '2.3.6', '2.5.9', '0.8.0', '2.3.6', '2.3.6', '2.3.6', '0.8.0', '6.2.6'], 'name': ['ABC', 'ABC', 'TAC', 'TTT', 'TAC', 'ABC', 'TAC', 'TAC', 'TAC', 'ABC'] } df = pd.DataFrame(data) # 步骤1:处理日期并分组统计 df['Date'] = pd.to_datetime(df['Date']) df['Month'] = df['Date'].dt.month_name() df2 = df.groupby(['Month', 'inp', 'name']).size().reset_index(name='Count') # 步骤2:透视得到df3 df2['inp_name'] = df2['inp'] + '_' + df2['name'] df3 = df2.pivot(index='Month', columns='inp_name', values='Count').fillna(0).astype(int) # 步骤3:移除零值过多的列 zero_counts = df3.eq(0).sum(axis=0) df_final = df3.loc[:, zero_counts <= 2] print(df_final)
内容的提问来源于stack exchange,提问作者Bode
相关产品推荐
相关产品推荐

