如何在Pandas中无需循环对多列应用相同transform()方法?
按日期分组对多列批量标准化(无需循环实现)
原实现代码及需求
原代码通过循环逐列处理,实现按Date分组后对指定列应用自定义标准化函数norm_std(注:原代码中df_orig.columns[]存在语法错误,已修正为目标列列表):
import pandas as pd import numpy as np data = {'Date': ['2023-01-01', '2023-01-01','2023-01-01', '2023-01-03', '2023-01-03', '2023-01-03'], 'p1': [5000, 7000, 6421, 9851, 1385, 1475], 'p2': [22000, 27000, 25000, 29000, 35000, 1257] } df_orig = pd.DataFrame(data) def norm_std(x): return (x - np.mean(x))/np.std(x) def s_d(df, c): df[c] = df.groupby('Date')[c].transform(norm_std) # 原循环实现 for c in ['p1', 'p2']: s_d(df_orig, c)
需求:移除循环,实现对多列批量按日期分组应用标准化函数
无循环优化方案
方案1:利用groupby().transform直接处理多列
可以直接对目标列组应用transform,无需逐列循环,代码更简洁:
import pandas as pd import numpy as np data = {'Date': ['2023-01-01', '2023-01-01','2023-01-01', '2023-01-03', '2023-01-03', '2023-01-03'], 'p1': [5000, 7000, 6421, 9851, 1385, 1475], 'p2': [22000, 27000, 25000, 29000, 35000, 1257] } df_orig = pd.DataFrame(data) def norm_std(x): return (x - x.mean()) / x.std() # 直接对目标列分组后批量应用transform df_orig[['p1', 'p2']] = df_orig.groupby('Date')[['p1', 'p2']].transform(norm_std)
如果需要处理除Date外的所有列,可替换为df_orig.columns.drop('Date')获取目标列列表
方案2:使用内置Z-score函数简化实现
你的norm_std本质就是Z-score标准化,可直接调用scipy的内置函数,性能更优:
import pandas as pd from scipy.stats import zscore data = {'Date': ['2023-01-01', '2023-01-01','2023-01-01', '2023-01-03', '2023-01-03', '2023-01-03'], 'p1': [5000, 7000, 6421, 9851, 1385, 1475], 'p2': [22000, 27000, 25000, 29000, 35000, 1257] } df_orig = pd.DataFrame(data) # 分组后批量应用内置zscore函数 df_orig[['p1', 'p2']] = df_orig.groupby('Date')[['p1', 'p2']].transform(zscore)
该方法与自定义函数效果完全一致,且内置函数经过底层优化,处理大数据集时效率更高。
内容的提问来源于stack exchange,提问作者Bazman
相关产品推荐
相关产品推荐

