gpt4 book ai didi

python - 将多个 StandardScaler 应用到各个组?

转载 作者:行者123 更新时间:2023-12-01 01:03:17 30 4
gpt4 key购买 nike

是否有一种Python式的方法可以将sklearn的StandardScaler实例链接在一起以独立地按组缩放数据?即,如果我想找到独立缩放虹膜数据集的特征;我可以使用以下代码:

from sklearn.datasets import load_iris
data = load_iris()
df = pd.DataFrame(data['data'], columns=data['feature_names'])
df['class'] = data['target']

means = df.groupby('class').mean()
stds = df.groupby('class').std()

df_rescaled = (
(df.drop(['class'], 1) - means.reindex(df['class']).values) /
stds.reindex(df['class']).values)

在这里,我独立地减去每组的平均值并除以标准差。但是,当我有一个想要控制的分类变量时,携带这些方法和标准偏差有点困难,并且本质上是复制 StandardScaler 的行为。

是否有更 Pythonic/sklearn 友好的方法来实现这种类型的缩放?

最佳答案

当然,您可以使用任何 sklearn操作并将其应用于 groupby对象。

首先,一些方便的包装:

import typing
import pandas as pd

class SklearnWrapper:
def __init__(self, transform: typing.Callable):
self.transform = transform

def __call__(self, df):
transformed = self.transform.fit_transform(df.values)
return pd.DataFrame(transformed, columns=df.columns, index=df.index)

这将适用于任何 sklearn将您传递给一组。

最后是简单的用法:

from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler

data = load_iris()
df = pd.DataFrame(data["data"], columns=data["feature_names"])
df["class"] = data["target"]

df_rescaled = (
df.groupby("class")
.apply(SklearnWrapper(StandardScaler()))
.drop("class", axis="columns")
)

编辑:你几乎可以用 SklearnWrapper 做任何事情。 。以下是为每个组转换和反转此操作的示例(例如,不要覆盖转换对象) - 每次看到新组时都重新适合该对象(并将其添加到 list )。

我复制了一些 sklearn's功能以便于使用(您可以通过将适当的 string 传递给 _call_with_function 内部方法来使用任何您想要的功能来扩展它):

class SklearnWrapper:
def __init__(self, transformation: typing.Callable):
self.transformation = transformation
self._group_transforms = []
# Start with -1 and for each group up the pointer by one
self._pointer = -1

def _call_with_function(self, df: pd.DataFrame, function: str):
# If pointer >= len we are making a new apply, reset _pointer
if self._pointer >= len(self._group_transforms):
self._pointer = -1
self._pointer += 1
return pd.DataFrame(
getattr(self._group_transforms[self._pointer], function)(df.values),
columns=df.columns,
index=df.index,
)

def fit(self, df):
self._group_transforms.append(self.transformation.fit(df.values))
return self

def transform(self, df):
return self._call_with_function(df, "transform")

def fit_transform(self, df):
self.fit(df)
return self.transform(df)

def inverse_transform(self, df):
return self._call_with_function(df, "inverse_transform")

用法(分组变换、逆运算并再次应用):

data = load_iris()
df = pd.DataFrame(data["data"], columns=data["feature_names"])
df["class"] = data["target"]

# Create scaler outside the class
scaler = SklearnWrapper(StandardScaler())

# Fit and transform data (holding state)
df_rescaled = df.groupby("class").apply(scaler.fit_transform)

# Inverse the operation
df_inverted = df_rescaled.groupby("class").apply(scaler.inverse_transform)

# Apply transformation once again
df_transformed = (
df_inverted.groupby("class")
.apply(scaler.transform)
.drop("class", axis="columns")
)

关于python - 将多个 StandardScaler 应用到各个组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55601928/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com