Pandas行级MODE、均值计算及非零销量月份统计问题
Pandas DataFrame 新增统计列实现方案
关于众数的疑问解答
- 疑问1:当一行中有多个值出现频率相同时(如0和2各出现2次),Pandas原生
mode()方法会返回所有众数。要得到唯一值,需根据业务需求自定义规则,比如取最小的众数、取最大的众数,或者取第一个出现的众数。 - 疑问2:若一行内所有数值均不重复,每个值的出现频率都是1,严格来说所有值都是众数。实际业务中可根据需求返回第一个值、
NaN,或自定义默认值(如None)。
具体实现代码
1. 构造示例数据
import pandas as pd import numpy as np # 模拟业务数据:行对应产品,列对应各月销量 data = { '产品': ['A', 'B', 'C', 'D'], '当月': [0, 3, 5, 1], '前1月': [2, 3, 4, 2], '前2月': [0, 2, 3, 3], '前3月': [2, 1, 2, 4] } df = pd.DataFrame(data)
2. 定义行级统计函数
def row_stats(row): # 提取当前行的销量数据(排除产品名称列) sales_cols = ['当月', '前1月', '前2月', '前3月'] sales = row[sales_cols] # 计算众数:取第一个出现的众数,无有效众数时返回NaN mode_result = sales.mode() mode_val = mode_result.iloc[0] if not mode_result.empty else np.nan # 计算均值 mean_val = sales.mean() # 统计非零销量的月份数 non_zero_count = (sales != 0).sum() # 返回统计结果,指定列名 return pd.Series([mode_val, mean_val, non_zero_count], index=['MODE', '均值', '非零销量月份数'])
3. 应用函数并合并结果
# 对每行应用统计函数,合并到原DataFrame df = pd.concat([df, df.apply(row_stats, axis=1)], axis=1)
代码说明
- 众数处理:
sales.mode()返回行内所有众数,通过iloc[0]取第一个众数保证唯一性;如果需要取最小/最大众数,可改为mode_result.min()或mode_result.max()。 - 均值计算:
sales.mean()自动处理数值类型,若存在缺失值会自动忽略(需提前处理数据缺失的情况)。 - 非零月份统计:通过布尔索引
sales != 0筛选非零值,sum()统计符合条件的数量,高效直观。
最终结果示例
处理后的DataFrame如下:
| 产品 | 当月 | 前1月 | 前2月 | 前3月 | MODE | 均值 | 非零销量月份数 |
|---|---|---|---|---|---|---|---|
| A | 0 | 2 | 0 | 2 | 0 | 1.0 | 4 |
| B | 3 | 3 | 2 | 1 | 3 | 2.25 | 4 |
| C | 5 | 4 | 3 | 2 | 2 | 3.5 | 4 |
| D | 1 | 2 | 3 | 4 | 1 | 2.5 | 4 |
内容的提问来源于stack exchange,提问作者foliveir
相关产品推荐
相关产品推荐

