Я хочу применить масштабирование (используя StandardScaler () из sklearn.preprocessing) к фрейму данных pandas. Следующий код возвращает массив 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-packages / sklearn / preprocessing / data.py: 583: Предупреждение об устаревании: передача 1d-массивов в качестве данных устарела в версии 0.17. и вызовет ValueError в 0,19. Измените форму своих данных, используя X.reshape (-1, 1), если ваши данные имеют одну функцию, или X.reshape (1, -1) если он содержит один образец.

Поэтому я попробовал:

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

Но это дает:

Traceback (последний вызов последним): файл "./analyse.py", строка 91, в features = features.apply (lambda x: autoscaler.fit_transform (x.reshape (-1, 1))) Файл "/usr/lib/python3.5/site-packages/pandas/core/frame.py", строка 3972, в применять return self._apply_standard (f, axis, reduce = reduce) Файл "/usr/lib/python3.5/site-packages/pandas/core/frame.py", строка 4081, в _apply_standard result = self._constructor (data = results, index = index) Файл "/usr/lib/python3.5/site-packages/pandas/core/frame.py", строка 226, в инициализация mgr = self._init_dict (данные, индекс, столбцы, dtype = dtype) Файл "/usr/lib/python3.5/site-packages/pandas/core/frame.py", строка 363, в _init_dict dtype = dtype) Файл "/usr/lib/python3.5/site-packages/pandas/core/frame.py", строка 5163, в _arrays_to_mgr массивы = _homogenize (массивы, индекс, dtype) Файл "/usr/lib/python3.5/site-packages/pandas/core/frame.py", строка 5477, в _homogenize Raise_cast_failure = False) Файл "/usr/lib/python3.5/site-packages/pandas/core/series.py", строка 2885, в _sanitize_array поднять исключение («Данные должны быть одномерными») Исключение: данные должны быть одномерными

Как применить масштабирование к фрейму данных pandas, оставив фрейм данных нетронутым? По возможности без копирования данных.

Louic

Ответы (8)

Вы можете преобразовать DataFrame как массив numpy, используя as_matrix (). Пример на случайном наборе данных:

Изменить: Изменение as_matrix () на значений, (это не меняет результат) в соответствии с последним предложением as_matrix () docs выше:

Обычно рекомендуется использовать ".values".

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 DataFrame, чтобы получить scaled_features массив:

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 (Примечание: используйте аргументы ключевого слова index и columns, чтобы сохранить исходные индексы и имена столбцов:

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:

Обнаружил пакет sklearn-pandas. Он ориентирован на упрощение использования scikit-learn с пандами.sklearn-pandas особенно полезен, когда вам нужно применить более одного типа преобразования к подмножествам столбцов DataFrame, что является более распространенным сценарием. Это задокументировано, но именно так можно осуществить преобразование, которое мы только что выполнили.

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_scaled будет тем же фреймом данных, только теперь с масштабированными значениями

Вот что я сделал:

X.Column1 = StandardScaler().fit_transform(X.Column1.values.reshape(-1, 1))
features = ["col1", "col2", "col3", "col4"]
autoscaler = StandardScaler()
df[features] = autoscaler.fit_transform(df[features])

Вы можете попробовать этот код, это даст вам 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]

Вы можете напрямую назначить массив numpy фрейму данных, используя нарезку.

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

При повторном присвоении df.values ​​сохраняются как индекс, так и столбцы.

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

Вы можете смешивать несколько типов данных в scikit-learn, используя Neuraxle:

Вариант 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)

2022 WebDevInsider