Pandas DataFrame按Group分组应用BoxCox变换后新增列存回原表的实现问题
实现方案
前置注意项
scipy.stats.boxcox要求输入数据全为正数,若存在非正数值需先做平移处理- 该函数返回值为元组
(变换后的数组, 最优lambda参数),我们取第一个元素作为变换结果
推荐写法(自动对齐索引,无需手动处理顺序)
直接使用groupby.transform完成分组变换,该API会自动将分组计算结果和原DataFrame的行索引对齐,不会出现顺序错乱问题,代码更简洁:
import pandas as pd from scipy import stats def modify(df): transform_cols = ['Var_A', 'Var_B', 'Var_C'] # 逐列分组应用BoxCox变换,直接赋值到新列 for col in transform_cols: df[f"{col}_boxcox"] = df.groupby("Group")[col].transform( lambda x: stats.boxcox(x)[0] ) return df
沿用原有循环逻辑的写法
如果你要保留当前手写遍历分组的实现,核心是通过分组自带的原始索引进行赋值,保证对应关系正确:
import pandas as pd from scipy import stats def modify(df): df = df.sort_values("Group").copy() transform_cols = ['Var_A', 'Var_B', 'Var_C'] # 提前初始化新列 for col in transform_cols: df[f"{col}_boxcox"] = 0.0 grouped = df.groupby("Group") for name, group in grouped: for col in transform_cols: # 计算变换结果 bc_res = stats.boxcox(group[col])[0] # 按当前分组的原始索引把结果写回原DataFrame df.loc[group.index, f"{col}_boxcox"] = bc_res return df
两种写法都完全保留原DataFrame的行顺序,新生成的变换列和原数据行一一对应。如果需要留存每个分组每个列的最优lambda参数,额外新增字典存储
stats.boxcox(x)[1]的返回值即可。
内容的提问来源于stack exchange,提问作者logisticregress
相关产品推荐
相关产品推荐

