팬더에서 데이터 정규화


131

팬더 데이터 프레임이 있다고 가정합니다. df .

데이터 프레임의 열 현명한 평균을 계산하고 싶습니다.

이것은 쉬워요:

df.apply(average) 

그런 다음 현명한 범위는 max (col)-min (col)입니다. 이것은 다시 쉽습니다.

df.apply(max) - df.apply(min)

이제 각 요소에 대해 열 평균을 빼고 열 범위로 나누고 싶습니다. 어떻게 해야할지 모르겠습니다.

어떤 도움 / 포인터라도 대단히 감사합니다.

답변:


225
In [92]: df
Out[92]:
           a         b          c         d
A  -0.488816  0.863769   4.325608 -4.721202
B -11.937097  2.993993 -12.916784 -1.086236
C  -5.569493  4.672679  -2.168464 -9.315900
D   8.892368  0.932785   4.535396  0.598124

In [93]: df_norm = (df - df.mean()) / (df.max() - df.min())

In [94]: df_norm
Out[94]:
          a         b         c         d
A  0.085789 -0.394348  0.337016 -0.109935
B -0.463830  0.164926 -0.650963  0.256714
C -0.158129  0.605652 -0.035090 -0.573389
D  0.536170 -0.376229  0.349037  0.426611

In [95]: df_norm.mean()
Out[95]:
a   -2.081668e-17
b    4.857226e-17
c    1.734723e-17
d   -1.040834e-17

In [96]: df_norm.max() - df_norm.min()
Out[96]:
a    1
b    1
c    1
d    1

서브 세트를 정규화하려는 경우이를 수행 할 수있는 방법이 있습니까? 해당 행을 말 AB는 별도로 정상화하려는 더 큰 그룹 요소의 일부 CD.
Amyunimus

서브 세트를 선택하고 이전과 같이 계산하십시오. 데이터 색인 및 선택 방법에 대한 내용은 pandas.pydata.org/pandas-docs/stable/indexing.html 을 참조하십시오
Wouter Overmeire

17
당신이 당신의 값이 필요한 경우>가 되실 0 : df_norm = (DF - df.min ()) / (df.max () - df.min ())
Dayvid 올리베이라

1
0과 1 사이의 값을 얻으려면 첫 번째 대괄호에서 df.mean ()이 아니라 df_norm = (df-df.min ()) / (df.max ()-df.min ())이어야합니다.
jnPy

2
데이터 프레임에 일부 열에 문자열이있는 경우이 답변을
netskink

73

sklearn라이브러리를 가져와도 괜찮다 면 블로그에서 언급 한 방법을 추천합니다 .

import pandas as pd
from sklearn import preprocessing

data = {'score': [234,24,14,27,-74,46,73,-18,59,160]}
cols = data.columns
df = pd.DataFrame(data)
df

min_max_scaler = preprocessing.MinMaxScaler()
np_scaled = min_max_scaler.fit_transform(df)
df_normalized = pd.DataFrame(np_scaled, columns = cols)
df_normalized

2
블로그 게시물에 대한 링크가 종료되었습니다. 작동하는 것이 있습니까?
marts

3
단위 정규 정규화 된 데이터를 생성하는 해당 방법을 StandardScaler라고합니다.
abeboparebop

다른 곳에서 비슷한 해결책을 찾았습니다. 문제는 np_scaled 부분에서 2D 배열을 기대하는 오류가 표시되었지만 입력은 1D 배열이므로 reshape (-1,1)을 사용하는 것이 좋습니다. 모양을 바꿀 때이 문제를 해결하는 방법도 작동하지 않습니다.
deadcode December

작업하는 numpy & sklearn의 버전에 따라 경고가 표시 될 수 있지만 일반적으로 작동합니다. np_scaled = min_max_scaler.fit_transform(df.score.astype(float).values.reshape(-1, 1))
Jaeyoung Chun

33

apply이것을 위해 사용할 수 있으며 조금 더 깔끔합니다.

import numpy as np
import pandas as pd

np.random.seed(1)

df = pd.DataFrame(np.random.randn(4,4)* 4 + 3)

          0         1         2         3
0  9.497381  0.552974  0.887313 -1.291874
1  6.461631 -6.206155  9.979247 -0.044828
2  4.276156  2.002518  8.848432 -5.240563
3  1.710331  1.463783  7.535078 -1.399565

df.apply(lambda x: (x - np.mean(x)) / (np.max(x) - np.min(x)))

          0         1         2         3
0  0.515087  0.133967 -0.651699  0.135175
1  0.125241 -0.689446  0.348301  0.375188
2 -0.155414  0.310554  0.223925 -0.624812
3 -0.484913  0.244924  0.079473  0.114448

또한 groupby관련 열을 선택 하면와 함께 잘 작동합니다 .

df['grp'] = ['A', 'A', 'B', 'B']

          0         1         2         3 grp
0  9.497381  0.552974  0.887313 -1.291874   A
1  6.461631 -6.206155  9.979247 -0.044828   A
2  4.276156  2.002518  8.848432 -5.240563   B
3  1.710331  1.463783  7.535078 -1.399565   B


df.groupby(['grp'])[[0,1,2,3]].apply(lambda x: (x - np.mean(x)) / (np.max(x) - np.min(x)))

     0    1    2    3
0  0.5  0.5 -0.5 -0.5
1 -0.5 -0.5  0.5  0.5
2  0.5  0.5  0.5 -0.5
3 -0.5 -0.5 -0.5  0.5

2

: 약간 변형에서 파이썬 Dataframe 팬더 : 정규화 데이터를 0.01 내지 0.99 사이?그러나 의견 중 일부는 관련이 있다고 생각했습니다 (재 게시로 간주되면 죄송합니다 ...)

데이텀 또는 z- 점수의 정규 백분위 수가 충분하지 않은 맞춤형 정규화를 원했습니다. 때로는 모집단의 가능한 최대 및 최소값이 무엇인지 알았으므로 샘플 또는 다른 중간 점 또는 다른 것을 제외하고는 그것을 정의하고 싶었습니다! 이것은 종종 0과 1 사이의 모든 입력을 원할 수있는 신경망에 대한 데이터의 크기를 조정하고 정규화하는 데 유용 할 수 있지만 백분위 수와 stdev는 샘플 표지를 가정하기 때문에 일부 데이터는보다 사용자 정의 된 방식으로 스케일링해야 할 수도 있습니다. 우리는 때때로 이것이 사실이 아니라는 것을 알고 있습니다. 히트 맵에서 데이터를 시각화 할 때 매우 유용했습니다. 그래서 나는 사용자 정의 함수를 만들었습니다 (가능한 한 쉽게 읽을 수 있도록 코드의 추가 단계를 사용했습니다).

def NormData(s,low='min',center='mid',hi='max',insideout=False,shrinkfactor=0.):    
    if low=='min':
        low=min(s)
    elif low=='abs':
        low=max(abs(min(s)),abs(max(s)))*-1.#sign(min(s))
    if hi=='max':
        hi=max(s)
    elif hi=='abs':
        hi=max(abs(min(s)),abs(max(s)))*1.#sign(max(s))

    if center=='mid':
        center=(max(s)+min(s))/2
    elif center=='avg':
        center=mean(s)
    elif center=='median':
        center=median(s)

    s2=[x-center for x in s]
    hi=hi-center
    low=low-center
    center=0.

    r=[]

    for x in s2:
        if x<low:
            r.append(0.)
        elif x>hi:
            r.append(1.)
        else:
            if x>=center:
                r.append((x-center)/(hi-center)*0.5+0.5)
            else:
                r.append((x-low)/(center-low)*0.5+0.)

    if insideout==True:
        ir=[(1.-abs(z-0.5)*2.) for z in r]
        r=ir

    rr =[x-(x-0.5)*shrinkfactor for x in r]    
    return rr

팬더 시리즈 또는 목록을 가져와 지정된 낮은, 중앙 및 높은 지점으로 정규화합니다. 또한 수축 계수가 있습니다! 끝점 0과 1에서 멀리 떨어져 데이터를 축소 할 수 있도록 (matplotlib에서 컬러 맵을 결합 할 때이 작업을 수행해야했습니다 : Matplotlib을 사용하여 둘 이상의 컬러 맵이있는 단일 pcolormesh ) 코드의 작동 방식을 볼 수는 있지만 기본적으로 표본에 [-5,1,10] 값이 있지만 -7에서 7까지의 범위를 기준으로 정규화하려고합니다 (따라서 7보다 큰 값은 "10"이 효과적으로 7로 처리됨). 256 RGB 컬러 맵에 맞게 축소하십시오.

#In[1]
NormData([-5,2,10],low=-7,center=1,hi=7,shrinkfactor=2./256)
#Out[1]
[0.1279296875, 0.5826822916666667, 0.99609375]

또한 데이터를 뒤집을 수도 있습니다 ... 이상하게 보일 수 있지만 히트 매핑에 유용하다는 것을 알았습니다. hi / low가 아닌 ​​0에 가까운 값에 대해 더 어두운 색상을 원한다고 가정 해보십시오. insideout = True 인 정규화 된 데이터를 기반으로 히트 맵을 만들 수 있습니다.

#In[2]
NormData([-5,2,10],low=-7,center=1,hi=7,insideout=True,shrinkfactor=2./256)
#Out[2]
[0.251953125, 0.8307291666666666, 0.00390625]

중심에 가장 가까운 "2"는 "1"로 정의됩니다.

어쨌든 유용한 응용 프로그램을 가질 수있는 다른 방법으로 데이터의 크기를 조정하려는 경우 응용 프로그램이 적절하다고 생각했습니다.


모든 if / else 문 을 함수 가 포함 된 사전으로 바꿀 수 있습니다 . 그러면 좀 더 깨끗해 보입니다.
Roald

꽤 깔끔합니다. 다음에 염두에 두겠습니다. 감사합니다!
Vlox

0

이것은 열 방식으로 수행하는 방법입니다.

[df[col].update((df[col] - df[col].min()) / (df[col].max() - df[col].min())) for col in df.columns]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.