如何在Pandas分组数据上应用StandardScaler的fit_transform方法
分组后对DataFrame列应用StandardScaler标准化的解决方案
问题背景
原始DataFrame结构:
| group | data | other |
|---|---|---|
| A | 1 | a |
| A | 2 | b |
| A | 3 | ad |
| A | 4 | aw |
| A | 5 | ad |
| B | 100 | ta |
| B | 200 | as |
| B | 300 | ab |
| B | 400 | ax |
| B | 500 | ad |
需求:按group列分组后,对每个组的data列单独应用StandardScaler().fit_transform()进行标准化。
原代码(多组场景下失效):
df['data'] = pd.DataFrame(scaler.fit_transform(df.groupby('group').data.values.reshape(-1,1)))
期望输出(data列为标准化后结果,保留4位小数):
| group | data | other |
|---|---|---|
| A | -1.4142 | a |
| A | -0.7071 | b |
| A | 0.0000 | ad |
| A | 0.7071 | aw |
| A | 1.4142 | ad |
| B | -1.4142 | ta |
| B | -0.7071 | as |
| B | 0.0000 | ab |
| B | 0.7071 | ax |
| B | 1.4142 | ad |
问题原因
原代码错误在于:df.groupby('group').data.values会将所有分组的data值合并为一个一维数组,后续的标准化是基于全局的均值和标准差,而非每个分组自身的统计量,导致分组内的标准化逻辑失效。
解决方案
需要对每个分组单独实例化StandardScaler并执行fit_transform,可以通过两种方式实现:
方法1:使用groupby.apply
from sklearn.preprocessing import StandardScaler import pandas as pd # 构造示例数据(已有DataFrame可跳过此步) df = pd.DataFrame({ 'group': ['A']*5 + ['B']*5, 'data': [1,2,3,4,5,100,200,300,400,500], 'other': ['a','b','ad','aw','ad','ta','as','ab','ax','ad'] }) def scale_single_group(group): scaler = StandardScaler() # 传入二维数组适配fit_transform的输入要求 group['data'] = scaler.fit_transform(group[['data']]) return group # 按分组应用函数,group_keys=False避免额外添加分组键索引 df_scaled = df.groupby('group', group_keys=False).apply(scale_single_group) # 格式化输出保留4位小数 print(df_scaled.round(4))
方法2:使用groupby.transform(更简洁)
df['data'] = df.groupby('group')['data'].transform( lambda x: StandardScaler().fit_transform(x.values.reshape(-1,1)).flatten() ) print(df.round(4))
两种方法均能实现按分组单独标准化的需求,最终输出与期望结果一致。
内容的提问来源于stack exchange,提问作者Krit Pattamadit
相关产品推荐
相关产品推荐

