You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas按分组批量缩放多列并实现逆变换的问题求助

解决多分组MinMaxScaler缩放后逆变换错误的问题

你遇到的问题核心是共用了同一个MinMaxScaler实例处理不同分组:当处理第二个分组(Customer B)时,scaler会重新拟合B的数据,直接覆盖掉之前拟合Customer A的参数,导致逆变换Customer A时用的是B的缩放规则,结果自然出错。

下面是完整的解决方案,我们会为每个分组单独创建并保存对应的Scaler实例,确保缩放和逆变换都使用对应分组的规则:

步骤1:还原原始数据结构

先把你的数据恢复成初始的DataFrame结构(如果之前修改过列名的话):

import pandas as pd
from sklearn.preprocessing import MinMaxScaler

# 构建原始数据
data = {
    ('X_data', 'Customer'): ['A']*5 + ['B']*7,
    ('X_data', '0'): [855.0, 989.0, 454.0, 574.0, 395.0, 875.0, 999.0, 434.0, 564.0, 345.0, 798.0, 815.0],
    ('X_data', '1'): [989.0, 454.0, 574.0, 395.0, 162.0, 999.0, 434.0, 564.0, 345.0, 798.0, 815.0, 929.0],
    ('X_data', '2'): [454.0, 574.0, 395.0, 162.0, 123.0, 434.0, 564.0, 345.0, 798.0, 815.0, 929.0, 444.0],
    ('X_data', '3'): [574.0, 395.0, 162.0, 123.0, 342.0, 564.0, 345.0, 798.0, 815.0, 929.0, 444.0, 554.0],
    ('y_data', 'Customer'): ['A']*5 + ['B']*7,
    ('y_data', '0'): [395.0, 162.0, 123.0, 342.0, 232.0, 345.0, 798.0, 815.0, 929.0, 444.0, 554.0, 395.0],
    ('y_data', '1'): [162.0, 123.0, 342.0, 232.0, 657.0, 798.0, 815.0, 929.0, 444.0, 554.0, 395.0, 768.0]
}

df = pd.DataFrame(data)
X_data = df['X_data']
y_data = df['y_data']

步骤2:为每个分组单独训练并保存Scaler

用字典存储每个Customer对应的Scaler实例,分别处理X_data和y_data的所有数值列:

# 存储X_data各分组的Scaler
x_scalers = {}
scaled_X = X_data.copy()
x_num_cols = scaled_X.columns.drop('Customer')  # 排除Customer列,只处理数值列

for customer, group in scaled_X.groupby('Customer'):
    scaler = MinMaxScaler()
    # 拟合当前分组并完成缩放
    scaled_values = scaler.fit_transform(group[x_num_cols])
    scaled_X.loc[group.index, x_num_cols] = scaled_values
    # 保存当前分组的Scaler,用于后续逆变换
    x_scalers[customer] = scaler

# 同理处理y_data
y_scalers = {}
scaled_y = y_data.copy()
y_num_cols = scaled_y.columns.drop('Customer')

for customer, group in scaled_y.groupby('Customer'):
    scaler = MinMaxScaler()
    scaled_values = scaler.fit_transform(group[y_num_cols])
    scaled_y.loc[group.index, y_num_cols] = scaled_values
    y_scalers[customer] = scaler

步骤3:用对应Scaler完成逆变换

现在调用每个分组专属的Scaler进行逆变换,就能得到准确的原始数据:

# 逆变换X_data
inv_X = scaled_X.copy()
for customer, group in inv_X.groupby('Customer'):
    scaler = x_scalers[customer]
    inv_values = scaler.inverse_transform(group[x_num_cols])
    inv_X.loc[group.index, x_num_cols] = inv_values

# 逆变换y_data
inv_y = scaled_y.copy()
for customer, group in inv_y.groupby('Customer'):
    scaler = y_scalers[customer]
    inv_values = scaler.inverse_transform(group[y_num_cols])
    inv_y.loc[group.index, y_num_cols] = inv_values

# 验证结果(和原始数据完全一致)
print("X_data逆变换结果:")
print(inv_X.round(2))
print("\ny_data逆变换结果:")
print(inv_y.round(2))

你的原始代码出错原因

在你原来的代码里,x_scaler是一个全局实例:

  • 处理Customer A时,x_scaler拟合了A的0列数据
  • 处理Customer B时,x_scaler会重新拟合B的0列数据,直接覆盖了A的拟合参数
  • 逆变换时,x_scaler已经是拟合B后的状态,所以逆变换A的数据时用的是B的min/max,结果自然错误

而上面的方案为每个分组单独创建Scaler,彻底避免了参数被覆盖的问题,确保每个分组的缩放和逆变换都使用自己的规则。

内容的提问来源于stack exchange,提问作者mukesh tech01

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:27:51