[python] sklearn으로 확장 가능한 팬더 데이터 프레임 열

혼합 유형 열이있는 팬더 데이터 프레임이 있으며 일부 열에 sklearn의 min_max_scaler를 적용하고 싶습니다. 이상적으로는 이러한 변형을 제자리에서 수행하고 싶지만 아직 그렇게 할 방법을 찾지 못했습니다. 작동하는 다음 코드를 작성했습니다.

import pandas as pd
import numpy as np
from sklearn import preprocessing

scaler = preprocessing.MinMaxScaler()

dfTest = pd.DataFrame({'A':[14.00,90.20,90.95,96.27,91.21],'B':[103.02,107.26,110.35,114.23,114.68], 'C':['big','small','big','small','small']})
min_max_scaler = preprocessing.MinMaxScaler()

def scaleColumns(df, cols_to_scale):
    for col in cols_to_scale:
        df[col] = pd.DataFrame(min_max_scaler.fit_transform(pd.DataFrame(dfTest[col])),columns=[col])
    return df

dfTest

    A   B   C
0    14.00   103.02  big
1    90.20   107.26  small
2    90.95   110.35  big
3    96.27   114.23  small
4    91.21   114.68  small

scaled_df = scaleColumns(dfTest,['A','B'])
scaled_df

A   B   C
0    0.000000    0.000000    big
1    0.926219    0.363636    small
2    0.935335    0.628645    big
3    1.000000    0.961407    small
4    0.938495    1.000000    small

이것이 이것이이 변환을 수행하는 가장 바람직하고 효율적인 방법인지 궁금합니다. 더 나은 df.apply를 사용할 수있는 방법이 있습니까?

또한 다음 코드를 작동시킬 수 없다는 것에 놀랐습니다.

bad_output = min_max_scaler.fit_transform(dfTest['A'])

전체 데이터 프레임을 스케일러에 전달하면 작동합니다.

dfTest2 = dfTest.drop('C', axis = 1)
good_output = min_max_scaler.fit_transform(dfTest2)
good_output

스케일러에 시리즈를 전달하지 못하는 이유가 혼란 스럽습니다. 위의 전체 작업 코드에서 시리즈를 스케일러로 전달하고 데이터 프레임 열 =을 스케일링 된 시리즈로 설정하려고했습니다. 나는이 질문이 다른 곳에서 묻는 것을 보았지만 좋은 대답을 찾지 못했습니다. 여기에서 무슨 일이 일어나고 있는지 이해하는 데 도움이 될 것입니다!



답변

이전 버전 pandas이 이것을 막았 는지 확실하지 않지만 이제 다음 스 니펫이 완벽하게 작동하고 사용하지 않고도 원하는 것을 정확하게 생성합니다.apply

>>> import pandas as pd
>>> from sklearn.preprocessing import MinMaxScaler


>>> scaler = MinMaxScaler()

>>> dfTest = pd.DataFrame({'A':[14.00,90.20,90.95,96.27,91.21],
                           'B':[103.02,107.26,110.35,114.23,114.68],
                           'C':['big','small','big','small','small']})

>>> dfTest[['A', 'B']] = scaler.fit_transform(dfTest[['A', 'B']])

>>> dfTest
          A         B      C
0  0.000000  0.000000    big
1  0.926219  0.363636  small
2  0.935335  0.628645    big
3  1.000000  0.961407  small
4  0.938495  1.000000  small


답변

이렇게요?

dfTest = pd.DataFrame({
           'A':[14.00,90.20,90.95,96.27,91.21],
           'B':[103.02,107.26,110.35,114.23,114.68],
           'C':['big','small','big','small','small']
         })
dfTest[['A','B']] = dfTest[['A','B']].apply(
                           lambda x: MinMaxScaler().fit_transform(x))
dfTest

    A           B           C
0   0.000000    0.000000    big
1   0.926219    0.363636    small
2   0.935335    0.628645    big
3   1.000000    0.961407    small
4   0.938495    1.000000    small


답변

pir의 의견에서 언급 했듯이이 .apply(lambda el: scale.fit_transform(el))방법은 다음 경고를 생성합니다.

DeprecationWarning : 0.17에서 데이터가 더 이상 사용되지 않으므로 1d 배열을 전달하면 0.19에서 ValueError가 발생합니다. 데이터에 단일 기능이있는 경우 X.reshape (-1, 1)을 사용하거나 단일 샘플이 포함 된 경우 X.reshape (1, -1)을 사용하여 데이터를 재구성하십시오.

열을 numpy 배열로 변환하면 작업을 수행해야합니다 (StandardScaler를 선호합니다).

from sklearn.preprocessing import StandardScaler
scale = StandardScaler()

dfTest[['A','B','C']] = scale.fit_transform(dfTest[['A','B','C']].as_matrix())

편집 년 11 월 2018 (팬더에 대한 테스트 0.23.4 ) –

Rob Murray가 주석에서 언급했듯이 현재 (v0.23.4) 버전의 pandas .as_matrix()는을 반환합니다 FutureWarning. 따라서 다음과 같이 바꿔야합니다 .values.

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()

scaler.fit_transform(dfTest[['A','B']].values)

편집 2019년 5월은 (팬더에 대한 테스트 0.24.2 ) –

joelostblom이 주석에서 언급했듯이 ” . 대신에 0.24.0사용 .to_numpy()하는 것이 좋습니다 .values.”

업데이트 된 예 :

import pandas as pd
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
dfTest = pd.DataFrame({
               'A':[14.00,90.20,90.95,96.27,91.21],
               'B':[103.02,107.26,110.35,114.23,114.68],
               'C':['big','small','big','small','small']
             })
dfTest[['A', 'B']] = scaler.fit_transform(dfTest[['A','B']].to_numpy())
dfTest
      A         B      C
0 -1.995290 -1.571117    big
1  0.436356 -0.603995  small
2  0.460289  0.100818    big
3  0.630058  0.985826  small
4  0.468586  1.088469  small


답변

df = pd.DataFrame(scale.fit_transform(df.values), columns=df.columns, index=df.index)

감가 상각 경고없이 작동해야합니다.


답변

다음을 사용해서 pandas만 할 수 있습니다 .

In [235]:
dfTest = pd.DataFrame({'A':[14.00,90.20,90.95,96.27,91.21],'B':[103.02,107.26,110.35,114.23,114.68], 'C':['big','small','big','small','small']})
df = dfTest[['A', 'B']]
df_norm = (df - df.min()) / (df.max() - df.min())
print df_norm
print pd.concat((df_norm, dfTest.C),1)

          A         B
0  0.000000  0.000000
1  0.926219  0.363636
2  0.935335  0.628645
3  1.000000  0.961407
4  0.938495  1.000000
          A         B      C
0  0.000000  0.000000    big
1  0.926219  0.363636  small
2  0.935335  0.628645    big
3  1.000000  0.961407  small
4  0.938495  1.000000  small


답변

나는 그것이 매우 오래된 의견이라는 것을 알고 있지만 여전히 :

단일 괄호 (dfTest['A'])를 사용 하는 대신 이중 괄호를 사용하십시오 (dfTest[['A']]).

즉 : min_max_scaler.fit_transform(dfTest[['A']]).

나는 이것이 원하는 결과를 줄 것이라고 믿습니다.


답변