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

基于条件的标准化求助:按Rating分组标准化Score列

按分组实现Score的标准化解决方案

没错,scikit-learn里的标准缩放器(比如StandardScaler)确实不支持直接按分组做标准化——它默认是对整个数据集做全局处理的。不过别担心,有几种很实用的方法能实现你要的按Rating分组标准化Score的需求,我给你一步步拆解:

先明确你的示例数据

首先把你提供的数据整理成清晰的表格,方便对照结果:

序号ScoreRating预期标准化结果
1201200-1.264911064
2301300-1.264911064
3401200-0.632455532
4501300-0.632455532
56012000
67013000
78012000.632455532
89013000.632455532
910012001.264911064
1011013001.264911064

方法1:用Pandas groupby + transform快速实现(最推荐)

如果你已经在用Pandas处理数据,这是最简单高效的方式。核心思路是按Rating分组,然后对每个组的Score单独应用标准化逻辑,和sklearn的StandardScaler逻辑完全一致。

代码示例:

import pandas as pd
from sklearn.preprocessing import StandardScaler

# 构造你的数据集
data = pd.DataFrame({
    'Score': [20, 30, 40, 50, 60, 70, 80, 90, 100, 110],
    'Rating': [1200, 1300, 1200, 1300, 1200, 1300, 1200, 1300, 1200, 1300]
})

# 按Rating分组,对每个组的Score做Z-score标准化
scaler = StandardScaler()
data['standardized_score'] = data.groupby('Rating')['Score'].transform(
    lambda x: scaler.fit_transform(x.values.reshape(-1, 1)).flatten()
)

# 查看结果
print(data[['Score', 'Rating', 'standardized_score']])

运行这段代码后,standardized_score列会和你给出的预期结果完全匹配。


方法2:自定义sklearn Transformer(适配sklearn工作流)

如果你需要把这个分组标准化逻辑融入到sklearn的Pipeline、GridSearch等工作流里,可以自定义一个符合sklearn规范的Transformer:

from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.preprocessing import StandardScaler
import pandas as pd

class GroupStandardScaler(BaseEstimator, TransformerMixin):
    def __init__(self, group_col):
        self.group_col = group_col  # 指定分组列名
        self.group_scalers = {}     # 存储每个分组对应的缩放器

    def fit(self, X, y=None):
        # X需要是Pandas DataFrame
        for group_label, group_data in X.groupby(self.group_col):
            # 对每个分组的特征列(排除分组列)拟合缩放器
            scaler = StandardScaler()
            scaler.fit(group_data.drop(self.group_col, axis=1))
            self.group_scalers[group_label] = scaler
        return self

    def transform(self, X, y=None):
        transformed_dfs = []
        for group_label, group_data in X.groupby(self.group_col):
            # 用对应分组的缩放器转换数据
            scaled_features = self.group_scalers[group_label].transform(
                group_data.drop(self.group_col, axis=1)
            )
            # 转换回DataFrame并保留分组列和索引
            scaled_df = pd.DataFrame(
                scaled_features,
                columns=group_data.drop(self.group_col, axis=1).columns,
                index=group_data.index
            )
            scaled_df[self.group_col] = group_label
            transformed_dfs.append(scaled_df)
        # 合并后按原索引排序,保持数据顺序一致
        return pd.concat(transformed_dfs).sort_index()

使用方式示例:

# 初始化自定义缩放器,指定分组列为Rating
group_scaler = GroupStandardScaler(group_col='Rating')

# 拟合并转换数据
scaled_data = group_scaler.fit_transform(data)

# 查看结果
print(scaled_data)

这样你就可以把这个自定义Transformer和其他sklearn组件(比如Pipeline)结合使用,完全适配sklearn的工作流。


补充提示

  • 上面的示例用的是Z-score标准化(均值为0,标准差为1),如果你需要其他标准化方式(比如Min-Max缩放),只需要把StandardScaler换成MinMaxScaler、RobustScaler等即可,逻辑完全一致。
  • 如果你的测试数据中出现了训练时未见过的分组,自定义Transformer会抛出KeyError,这时候可以在transform方法里添加默认处理逻辑(比如使用全局缩放器,或者跳过该分组)。

内容的提问来源于stack exchange,提问作者Ivan To

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:25:36