我有一个numpy数组X有3列,如下所示:
array([[ 3791, 2629, 0],
[ 1198760, 113989, 0],
[ 4120665, 0, 1],
...
前两列是连续值,最后一列是二进制(0,1)。我想将StandardScaler类仅应用于前两列。我目前正在通过以下方式执行此操作:
scaler = StandardScaler()
X_subset = scaler.fit_transform(X[:,[0,1]])
X_last_column = X[:, 2]
X_std = np.concatenate((X_subset, X_last_column[:, np.newaxis]), axis=1)
X_std的输出是:
array([[-0.34141308, -0.18316715, 0. ],
[-0.22171671, -0.17606473, 0. ],
[ 0.07096154, -0.18333483, 1. ],
...,
有没有办法一步完成这一切?我想将此作为管道的一部分包含在内,它将扩展前2列并保留最后一列二进制列。
答案 0 :(得分:2)
感谢您的答复。我最终使用了一个类来选择像这样的列:
payment.salonvo
然后我在管道中按如下方式使用FeatureUnion将StandardScaler仅适合连续变量:
class ItemSelector(BaseEstimator, TransformerMixin):
def __init__(self, columns):
self.columns = columns
def fit(self, x, y=None):
return self
def transform(self, data_array):
return data_array[:, self.columns]
这对我来说很好。
答案 1 :(得分:2)
从scikit-learn 0.20版本开始,您可以完全使用函数sklearn.compose.ColumnTransformer来实现此目的。
答案 2 :(得分:0)
我无法想到另一种方法来压缩你的代码,但你绝对可以在管道中使用你的转换。您必须定义一个扩展StandardScaler的类,该类仅对作为参数传递的列执行转换,保持其他列不变。请参阅此example中的代码,您必须编写类似于ItemSelector的代码。
答案 3 :(得分:0)
受skd建议扩展StandardScaler的启发,我提出了以下建议。它不是非常高效或强大(例如,您需要更新inverse_transform函数),但希望它是一个有用的起点:
class StandardScalerSelect(StandardScaler):
def __init__(self, copy=True, with_mean=True, with_std=True, cols=None):
self.cols = cols
super().__init__(copy, with_mean, with_std)
def transform(self, X):
not_transformed_ix = np.isin(np.array(X.columns), np.array(self.cols), invert=True)
# Still transforms all, just for convenience. For larger datasets
# will want to modify self.mean_ and self.scale_ so the dimensions match,
# and then just transform the subset
trans = super().transform(X)
trans[:,not_transformed_ix] = np.array(X.iloc[:,not_transformed_ix])
return trans