
本文详解如何在 pandas 中基于 id、hrz、tenor 多列分组,并对数值列(如 1–4)并行应用多个自定义统计检验函数(如 KS 检验、CVM 检验),最终生成结构清晰、可直接分析的宽格式结果表。
本文详解如何在 pandas 中基于 `id`、`hrz`、`tenor` 多列分组,并对数值列(如 `1`–`4`)并行应用多个自定义统计检验函数(如 ks 检验、cvm 检验),最终生成结构清晰、可直接分析的宽格式结果表。
在金融、风控或计量分析场景中,常需对时间序列数据按资产标识(如 id)、期限类型(如 tenor)和模型参数(如 hrz)分组,再对各期观测值批量执行分布一致性检验(如 Kolmogorov-Smirnov 或 Cramér–von Mises)。pandas 提供了灵活高效的 groupby().agg() 机制,配合合理的数据重构策略,可优雅实现该需求。
✅ 核心步骤概览
-
明确分组键与目标列:从原始 DataFrame 中分离出分组列(
['id', 'hrz', 'tenor'])和待聚合的数值列(排除date等非数值/辅助列); - 定义自定义函数:确保函数接收一维 Series(或 ndarray),返回标量结果(如 KS 统计量);
-
分组聚合 + 多函数并行应用:使用
agg()同时调用多个函数,支持字典映射或函数列表; -
结果重塑为所需格式:通过
stack()或concat()将多层列索引展平,并插入test列标识函数名。
? 示例代码实现
首先,确保导入必要依赖并定义检验函数:
import pandas as pd
import numpy as np
from scipy import stats
def ks_test(x):
# 注意:kstest 需传入未排序数据,但 uniform 检验通常需指定 cdf 形式;
# 此处修正为标准用法:检验是否服从 [0,1] 上的均匀分布
return stats.kstest(x, 'uniform').statistic
def cvm_test(x):
n = len(x)
if n < 2:
return np.nan
x_sorted = np.sort(x)
i = np.arange(1, n + 1)
w2 = (1 / (12 * n)) + np.sum((x_sorted - (2 * i - 1) / (2 * n)) ** 2)
return w2方法一:agg() + concat()(推荐用于函数命名明确、需控制输出顺序)
group_cols = ['id', 'hrz', 'tenor']
value_cols = df.columns.difference(group_cols + ['date']) # 自动提取 '1','2','3','4'
g = df.groupby(group_cols)[value_cols]
result = pd.concat({
'ks_test': g.agg(ks_test),
'cvm_test': g.agg(cvm_test)
}, names=['test']).reset_index()✅ 输出结构:test 作为首列,分组列紧随其后,各数值列保持原名,逻辑清晰、排序可控。
方法二:agg([f1, f2]) + stack()(简洁紧凑,适合快速探索)
result = (
df.groupby(group_cols)[value_cols]
.agg([ks_test, cvm_test])
.rename_axis([None, 'test'], axis=1) # 重命名列层级:(None, 'test')
.stack('test') # 将 'test' 层级压栈为行索引
.reset_index() # 转为常规 DataFrame
)✅ 输出结构:自动将函数名作为 test 列值,无需手动构造字典,代码更简练。
⚠️ 注意事项与最佳实践
-
函数输入兼容性:
agg()会将每列的每个分组子集以pd.Series形式传入函数,务必确保函数能处理Series(如x.values可显式转为np.ndarray); -
缺失值处理:若某分组内某列全为空,
agg()默认返回NaN;可在函数内添加x = x.dropna()预处理; -
性能优化:对大数据集,避免在函数内重复调用
np.sort()——agg()是逐列独立调用,无法跨列复用中间结果; - 结果验证:建议对小样本手动验证一个分组的 KS/CVM 值,确认统计逻辑与业务预期一致(例如:均匀性越强,KS 值越小);
-
扩展性提示:如需添加更多检验(如
ad_test,jarque_bera),只需在agg()字典或列表中追加即可,结构完全一致。
通过上述任一方法,你均可高效获得结构化、可直接用于下游分析或可视化的检验结果表,真正实现“一次分组、多函数并行、结果即用”。

















