分组使用MinMaxScaler后inverse_transform结果异常求助
问题分析
你遇到的逆变换失败问题,核心原因有两个:
- 数据类型错误:在缩放前你把
Price列转成了字符串格式('{:.2f}'.format(x)),但MinMaxScaler需要处理数值类型数据,字符串会直接打乱后续的计算逻辑。 - Scaler实例未按分组绑定:每个客户的价格范围差异极大(比如客户B的最大价格是142466027340.03,客户A的最大价格仅2342323.24),
MinMaxScaler的拟合参数(min_和scale_)是和分组强绑定的,但你逆变换时用的是同一个全局scaler,它只保留了最后一次拟合的分组参数,自然无法正确还原其他分组的数据。
解决方案
下面是修正后的完整代码,我们会为每个分组单独保存对应的scaler实例,同时全程保留数值类型进行处理:
import pandas as pd from sklearn.preprocessing import MinMaxScaler # 构建原始DataFrame(模拟你的数据) data = [ ["1/6/2019", "A", 142404534.13], ["1/7/2019", "A", 989.34], ["1/8/2019", "A", 45444.57], ["1/9/2019", "A", 574343.10], ["1/10/2019", "A", 23232.34], ["1/1/2019", "A", 923423.00], ["1/2/2019", "A", 332.00], ["1/3/2019", "A", 2342323.24], ["1/4/2019", "A", 232.00], ["1/5/2019", "A", 65.70], ["1/6/2019", "B", 875.46], ["1/7/2019", "B", 142466027340.03], ["1/8/2019", "B", 25.17], ["1/9/2019", "B", 1.01], ["1/10/2019", "B", 1.00], ["1/10/2019", "B", 57.61], ["1/6/2019", "B", 232232.78], ["1/7/2019", "B", 15.20], ["1/8/2019", "B", 44.56], ["1/9/2019", "B", 2323254.45], ["1/10/2019", "B", 395.45], ["1/10/2019", "B", 23423454.92], ["1/6/2019", "C", 34.12], ["1/7/2019", "C", 89.34], ["1/8/2019", "C", 44.57], ["1/9/2019", "C", 343.10], ["1/10/2019", "C", 232.34] ] df = pd.DataFrame(data, columns=["Date", "Customer", "Price"]) # 第一步:按分组拟合缩放,同时保存每个客户的scaler实例 scaler_dict = {} # 存储每个客户对应的scaler scaled_prices = [] for customer, group in df.groupby('Customer'): scaler = MinMaxScaler() # 对当前分组的Price进行缩放 group_scaled = scaler.fit_transform(group['Price'].values.reshape(-1, 1)).ravel() scaled_prices.extend(group_scaled) # 保存当前客户的scaler scaler_dict[customer] = scaler # 添加缩放后的数据到原DataFrame(仅格式化显示用,保留原始数值用于逆变换) df['Scaled_Price'] = scaled_prices df['Scaled_Price_Formatted'] = df['Scaled_Price'].apply(lambda x: '{:.2f}'.format(x)) # 第二步:用保存的scaler逆变换,还原原始价格 restored_prices = [] for idx, row in df.iterrows(): customer = row['Customer'] scaled_val = row['Scaled_Price'] # 获取当前客户对应的scaler scaler = scaler_dict[customer] # 执行逆变换 original_val = scaler.inverse_transform([[scaled_val]])[0][0] restored_prices.append(original_val) # 添加还原后的价格到DataFrame df['Restored_Price'] = restored_prices df['Restored_Price_Formatted'] = df['Restored_Price'].apply(lambda x: '{:.2f}'.format(x)) # 验证结果(查看前几行对比原始价格和还原价格) print(df[['Customer', 'Price', 'Scaled_Price_Formatted', 'Restored_Price_Formatted']].head())
关键细节说明
- 保留数值类型:缩放和逆变换全程使用
float类型处理,只在需要显示时格式化字符串,避免类型转换导致的计算错误。 - 分组绑定Scaler:用字典
scaler_dict存储每个客户对应的MinMaxScaler实例,确保逆变换时调用的是该分组专属的拟合参数。 - 逐行匹配逆变换:遍历每一行数据,根据客户匹配对应的scaler,保证每个缩放后的值都能被精准还原。
运行代码后,Restored_Price列的数值会和原始Price列完全一致(浮点精度范围内),解决你之前的逆变换错误问题。
内容的提问来源于stack exchange,提问作者mukesh tech01
相关产品推荐
相关产品推荐

