如何使用 sklearn 的适合_转换熊猫和返回数据帧,而不是麻木的数组?

我想将伸缩(使用 StandardScaler ()从 skearn.preprocess)应用到熊猫数据框架。下面的代码返回一个 numpy 数组,因此我失去了所有的列名和索引。这不是我想要的。

features = df[["col1", "col2", "col3", "col4"]]
autoscaler = StandardScaler()
features = autoscaler.fit_transform(features)

我在网上找到的一个“解决方案”是:

features = features.apply(lambda x: autoscaler.fit_transform(x))

这似乎有效,但引发了一个反对的警告:

/usr/lib/python3.5/site-package/sklearn/preprocess/data.py: 583: 在0.17中,传递1d 数组作为数据是不推荐的 并将在0.19中引发 ValueError 如果数据只有一个特性,则为 X.respe (-1,1)或 X.respe (1,-1) 如果它包含一个单一的样本。

因此我试着:

features = features.apply(lambda x: autoscaler.fit_transform(x.reshape(-1, 1)))

但这给出了:

回溯(最近的调用) : 文件“ ./analyse.py”,第91行,in Features = Features. application (lambda x: autoscaler.fit _ change (x.reshape (- 1,1)))文件 “/usr/lib/python3.5/site-packages/anda/core/frame.py”,第3972行,in 申请 返回“/usr/lib/python3.5/site-package/anda/core/frame.py”,第4081行,in 应用标准 Result = self _ structor (data = results,index = index) File“/usr/lib/python3.5/site-package/anda/core/frame.py”,第226行,in Init (数据、索引、列、 dtype = dtype)文件“/usr/lib/python3.5/site-package/anda/core/frame.py”,第363行,in (咒语) Dtype = dtype)文件“/usr/lib/python3.5/site-package/anda/core/frame.py”,第5163行,in _ array _ to _ mgr Array = _ homogenize (array,index,dtype) File“/usr/lib/python3.5/site-package/anda/core/frame.py”,第5477行,in 同质化 “/usr/lib/python3.5/site-package/anda/core/series.py”,第2885行, In _ sanitize _ array 异常(“数据必须是一维的”)异常: 数据必须是一维的

如何将缩放应用到熊猫数据框架,使数据框架保持完整? 如果可能的话,不复制数据。

177229 次浏览

您可以使用 as_matrix()将 DataFrame 转换为数字数组:

编辑:as_matrix()改为 values(不改变结果) ,按照上面的 as_matrix()文档的最后一句:

通常,建议使用“ . value”。

import pandas as pd
import numpy as np #for the random integer example
df = pd.DataFrame(np.random.randint(0.0,100.0,size=(10,4)),
index=range(10,20),
columns=['col1','col2','col3','col4'],
dtype='float64')

注意,指数是10-19:

In [14]: df.head(3)
Out[14]:
col1    col2    col3    col4
10  3   38  86  65
11  98  3   66  68
12  88  46  35  68

现在 fit_transform的数据框架得到 scaled_featuresarray:

from sklearn.preprocessing import StandardScaler
scaled_features = StandardScaler().fit_transform(df.values)


In [15]: scaled_features[:3,:] #lost the indices
Out[15]:
array([[-1.89007341,  0.05636005,  1.74514417,  0.46669562],
[ 1.26558518, -1.35264122,  0.82178747,  0.59282958],
[ 0.93341059,  0.37841748, -0.60941542,  0.59282958]])

将缩放后的数据分配给 DataFrame (注意: 使用 indexcolumns关键字参数保留原始索引和列名:

scaled_features_df = pd.DataFrame(scaled_features, index=df.index, columns=df.columns)


In [17]:  scaled_features_df.head(3)
Out[17]:
col1    col2    col3    col4
10  -1.890073   0.056360    1.745144    0.466696
11  1.265585    -1.352641   0.821787    0.592830
12  0.933411    0.378417    -0.609415   0.592830

编辑2:

发现了 臭鼬-熊猫的包裹。它的重点是使 scikit-学习更容易与熊猫一起使用。当需要对 DataFrame的列子集应用多种类型的转换时,sklearn-pandas尤其有用,这是一种更常见的场景。这是有记录的,但这就是我们如何实现刚才执行的转换的方法。

from sklearn_pandas import DataFrameMapper


mapper = DataFrameMapper([(df.columns, StandardScaler())])
scaled_features = mapper.fit_transform(df.copy(), 4)
scaled_features_df = pd.DataFrame(scaled_features, index=df.index, columns=df.columns)
import pandas as pd
from sklearn.preprocessing import StandardScaler


df = pd.read_csv('your file here')
ss = StandardScaler()
df_scaled = pd.DataFrame(ss.fit_transform(df),columns = df.columns)

Df _ scale 将是相同的数据框架,只是现在有了缩放值

您可以尝试这段代码,这将为您提供一个带有索引的 DataFrame

import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import load_boston # boston housing dataset


dt= load_boston().data
col= load_boston().feature_names


# Make a dataframe
df = pd.DataFrame(data=dt, columns=col)


# define a method to scale data, looping thru the columns, and passing a scaler
def scale_data(data, columns, scaler):
for col in columns:
data[col] = scaler.fit_transform(data[col].values.reshape(-1, 1))
return data


# specify a scaler, and call the method on boston data
scaler = StandardScaler()
df_scaled = scale_data(df, col, scaler)


# view first 10 rows of the scaled dataframe
df_scaled[0:10]

您可以使用 神经轴在 scikit-learn 中混合使用多种数据类型:

选项1: 放弃行名和列名

from neuraxle.pipeline import Pipeline
from neuraxle.base import NonFittableMixin, BaseStep


class PandasToNumpy(NonFittableMixin, BaseStep):
def transform(self, data_inputs, expected_outputs):
return data_inputs.values


pipeline = Pipeline([
PandasToNumpy(),
StandardScaler(),
])

然后,按照你的计划进行:

features = df[["col1", "col2", "col3", "col4"]]  # ... your df data
pipeline, scaled_features = pipeline.fit_transform(features)

选项2: 保留原始列名和行名

你甚至可以使用这样的包装器:

from neuraxle.pipeline import Pipeline
from neuraxle.base import MetaStepMixin, BaseStep


class PandasValuesChangerOf(MetaStepMixin, BaseStep):
def transform(self, data_inputs, expected_outputs):
new_data_inputs = self.wrapped.transform(data_inputs.values)
new_data_inputs = self._merge(data_inputs, new_data_inputs)
return new_data_inputs


def fit_transform(self, data_inputs, expected_outputs):
self.wrapped, new_data_inputs = self.wrapped.fit_transform(data_inputs.values)
new_data_inputs = self._merge(data_inputs, new_data_inputs)
return self, new_data_inputs


def _merge(self, data_inputs, new_data_inputs):
new_data_inputs = pd.DataFrame(
new_data_inputs,
index=data_inputs.index,
columns=data_inputs.columns
)
return new_data_inputs


df_scaler = PandasValuesChangerOf(StandardScaler())

然后,按照你的计划进行:

features = df[["col1", "col2", "col3", "col4"]]  # ... your df data
df_scaler, scaled_features = df_scaler.fit_transform(features)
features = ["col1", "col2", "col3", "col4"]
autoscaler = StandardScaler()
df[features] = autoscaler.fit_transform(df[features])

您可以使用 切片直接将一个数字数组分配给一个数据帧。

from sklearn.preprocessing import StandardScaler
features = df[["col1", "col2", "col3", "col4"]]
autoscaler = StandardScaler()
features[:] = autoscaler.fit_transform(features.values)

我就是这么做的:

X.Column1 = StandardScaler().fit_transform(X.Column1.values.reshape(-1, 1))

重新分配回 df.value 会同时保留索引和列。

df.values[:] = StandardScaler().fit_transform(df)

MinMaxScaler 可以将数组值返回到原始数据框架,也可以在 StandardScaler 上使用。

data_scaled = pd.DataFrame(scaled_features, index=df.index, columns=df.columns)

其中,data _ scale 是新的数据框架,scale _ properties = 数组标准化后的数据,df = 原始数据框架,我们需要返回索引和列。

对我有用:

from sklearn.preprocessing import StandardScaler


cols = list(train_df_x_num.columns)
scaler = StandardScaler()
train_df_x_num[cols] = scaler.fit_transform(train_df_x_num[cols])