पंडों में डेटा को सामान्य करें


131

मान लीजिए कि मेरे पास एक पांडा डेटा फ्रेम है df:

मैं डेटा फ्रेम के कॉलम वार माध्य की गणना करना चाहता हूं।

यह आसान है:

df.apply(average) 

फिर कॉलम वार रेंज अधिकतम (कॉल) - मिनट (कॉल)। यह फिर से आसान है:

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

क्या ऐसा करने का कोई तरीका है यदि आप एक सबसेट को सामान्य करना चाहते हैं? उस पंक्ति को कहें Aऔर Bएक बड़े समूहन कारक का हिस्सा है जिसे आप अलग से Cऔर सामान्य करना चाहते हैं D
अम्युनिमुस

पहले की तरह सब्मिट और गणना करें। डेटा इंडेक्स करने और चयन करने के तरीके पर pandas.pydata.org/pandas-docs/stable/indexing.html देखें
Wouter Overmeire

17
अगर आपको अपने मूल्यों की आवश्यकता है> 0: df_norm = (df - df.min ()) / (df.max () - df.min ())
Dayvid Oliveira

1
होना चाहिए df_norm = (df - df.min ()) - पहली कोष्ठक में (df.min () df.max ()) के बजाय df.mean से () 0 और 1 के बीच मूल्यों को प्राप्त करने के लिए /
jnPy

2
यदि आपके
डेटाफ़्रेम

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
ब्लॉग पोस्ट के लिए लिंक मर चुका है। क्या आपके पास एक काम है?
मार्ट

3
यूनिट-सामान्य सामान्यीकृत डेटा बनाने की संबंधित विधि को StandardScaler कहा जाता है।
abeboparebop

मुझे एक अन्य स्थान पर एक समान समाधान मिला। समस्या यह थी कि np_scaled भाग में, यह 2D सरणी की अपेक्षा एक त्रुटि दिखा रहा था, लेकिन इनपुट 1D सरणी है और यह अनुशंसा करता है कि हम reshape (-1,1) का उपयोग करें। किसी भी विचार यह कैसे हल करने के लिए के रूप में reshape भी काम नहीं कर रहा है।
डेडकोड

आपके द्वारा काम करने वाले सुपी और स्केलेर के किस संस्करण के आधार पर आपको चेतावनी मिल सकती है, लेकिन सामान्य तौर पर, यह काम करना चाहिए 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

से थोड़ा संशोधित: पायथन पंडस डेटाफ्रेम: 0.01 और 0.99 के बीच डेटा को सामान्य करें? लेकिन कुछ टिप्पणियों से लगा कि यह प्रासंगिक है (खेद है कि अगर एक repost हालांकि माना जाता है ...)

मैं चाहता था कि डेटम या जेड-स्कोर के नियमित प्रतिशत में सामान्यीकरण अनुकूलित हो। कभी-कभी मुझे पता होता था कि जनसंख्या की संभाव्य अधिकतम और न्यूनतम राशि क्या है, और इसलिए मैं इसे अपने नमूने के अलावा, या एक अलग मिडपॉइंट, या जो कुछ भी परिभाषित करना चाहता था! यह अक्सर तंत्रिका जाल के लिए डेटा को बदलने और सामान्य करने के लिए उपयोगी हो सकता है, जहां आप 0 और 1 के बीच सभी इनपुट चाहते हो सकते हैं, लेकिन आपके कुछ डेटा को अधिक अनुकूलित तरीके से स्केल करने की आवश्यकता हो सकती है ... क्योंकि प्रतिशत और stdevs अपना नमूना कवर मान लेते हैं जनसंख्या, लेकिन कभी-कभी हम जानते हैं कि यह सच नहीं है। हीटमैप में डेटा की कल्पना करते समय यह मेरे लिए भी बहुत उपयोगी था। इसलिए मैंने एक कस्टम फ़ंक्शन बनाया (इसे यथासंभव पठनीय बनाने के लिए कोड में अतिरिक्त चरणों का उपयोग किया गया):

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 से दूर करने की अनुमति देने के लिए ( मैटप्लोटलिब में कॉलोर्मैप्स को मिलाते समय मुझे ऐसा करना पड़ा था: मैटलपोटलिब का उपयोग करते हुए एक से अधिक कॉलोरामैप के साथ एकल पीसीओलेर्मेश ) तो आप संभावना कर सकते हैं कि कोड कैसे काम करता है, लेकिन मूल रूप से आप कहते हैं एक नमूने में [-5,1,10] मान हैं, लेकिन -7 से 7 की सीमा के आधार पर सामान्य करना चाहते हैं (7 से ऊपर कुछ भी, हमारे "10" को 7 के प्रभावी रूप से 2 के मध्य बिंदु के साथ माना जाता है) लेकिन इसे एक 256 आरजीबी कॉलॉर्मैप फिट करने के लिए सिकोड़ें:

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

यह आपके डेटा को बाहर भी चालू कर सकता है ... यह अजीब लग सकता है, लेकिन मैंने इसे हीटमैपिंग के लिए उपयोगी पाया। कहते हैं कि आप उच्च / कम के बजाय 0 के करीब मूल्यों के लिए एक गहरा रंग चाहते हैं। आप सामान्यीकृत डेटा के आधार पर हीटमैप कर सकते हैं जहां अंदर = सत्य:

#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 / अन्यथा विवरण बदल सकते हैं । तब थोड़ा साफ दिखता है।
रोनाल्ड

यह बहुत साफ है, मैं अगली बार ध्यान में रखूंगा, धन्यवाद!
Vlox

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.