【发布时间】:2021-09-22 03:06:48
【问题描述】:
我想通过另一列应用 StandardScaler 组。
例如我想标准化column1,但按grp1 分组,以便在grp1 的每个不同值中使用不同的平均值和标准差。
scikit learn 可以吗?还是我需要为每个组分别构建一个管道?
欢迎非 scikit 学习解决方案
【问题讨论】:
标签: scikit-learn
我想通过另一列应用 StandardScaler 组。
例如我想标准化column1,但按grp1 分组,以便在grp1 的每个不同值中使用不同的平均值和标准差。
scikit learn 可以吗?还是我需要为每个组分别构建一个管道?
欢迎非 scikit 学习解决方案
【问题讨论】:
标签: scikit-learn
没有执行此操作的内置解决方案。但是,您可以创建自己的 Transformer 来执行此操作。
以下自定义转换器正在为by 列中定义的每个唯一值执行拟合一个StandardScaler。此代码期望接收 DataFrame 作为输入。
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.preprocessing import StandardScaler
import pandas as pd
class GroupByScaler(BaseEstimator, TransformerMixin):
def __init__(self, by=None):
self.scalers = dict()
self.by = by
def fit(self, X, y = None):
self.cols = df.select_dtypes(exclude=['object']).columns
for val in X[self.by].unique():
mask = X[self.by]==val
X_sub = X.loc[mask, self.cols]
self.scalers[val] = StandardScaler().fit(X_sub)
return self
def transform(self, X, y = None):
for val in X[self.by].unique():
mask = X[self.by]==val
X.loc[mask, self.cols] = self.scalers[val].transform(X.loc[mask, self.cols])
return X
以下代码用于测试组 X 和 Y 与列 A 的缩放比例不同。
df = pd.DataFrame({'A': ['X', 'X', 'X', 'X', 'Y','Y','Y','Y'],
'B': [10, 10, 10, 10, 0, 1, 2, 4],
'C': [0, 1, 2, 4, 10, 10, 10, 10]})
GroupByScaler(by='A').fit_transform(df)
这将返回以下输出:
A B C
0 X 0.000000 -1.183216
1 X 0.000000 -0.507093
2 X 0.000000 0.169031
3 X 0.000000 1.521278
4 Y -1.183216 0.000000
5 Y -0.507093 0.000000
6 Y 0.169031 0.000000
7 Y 1.521278 0.000000
【讨论】: