2012-09-21 12 views
78

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

यह आसान है:

df.apply(average) 

तो स्तंभ बुद्धिमान सीमा अधिकतम (col) - मिनट (col)। यह फिर से आसान है:

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

अब प्रत्येक तत्व के लिए मैं अपने कॉलम की सीमा से अपने कॉलम के माध्य को घटाकर विभाजित करना चाहता हूं। मुझे यकीन नहीं है कि

किसी भी मदद/पॉइंटर्स की बहुत सराहना की जा रही है।

उत्तर

143
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 
+14

यह इतना स्पष्ट था कि मेरा दिमाग इसे स्वीकार नहीं कर सका :) – jason

+0

यदि आप सबसेट को सामान्य बनाना चाहते हैं तो ऐसा करने का कोई तरीका है? कहें कि पंक्ति 'ए' और' बी 'एक बड़े समूहीकरण कारक का हिस्सा हैं जिन्हें आप अलग से सामान्य रूप से 'सी' और' डी' से सामान्य करना चाहते हैं। – Amyunimus

+0

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

23

आप इस के लिए apply उपयोग कर सकते हैं, और यह neater एक सा है:

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 
48

हैं आपको sklearn लाइब्रेरी आयात करने पर कोई फर्क नहीं पड़ता, मैं this ब्लॉग पर बात की गई विधि की अनुशंसा करता हूं।

import pandas as pd 
from sklearn import preprocessing 

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

min_max_scaler = preprocessing.MinMaxScaler() 
np_scaled = min_max_scaler.fit_transform(df) 
df_normalized = pd.DataFrame(np_scaled) 
df_normalized 
+2

के बीच मान प्राप्त करने के लिए पहले ब्रैकेट में ब्लॉग पोस्ट का लिंक मर चुका है। क्या आपके पास कामकाजी है? – marts

+0

@marts किया ...! – astrojuanlu

+3

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

2

थोड़ा से संशोधित: Python Pandas Dataframe: Normalize data between 0.01 and 0.99? लेकिन से टिप्पणी के कुछ सोचा था कि यह प्रासंगिक था (खेद अगर एक पोस्ट हालांकि माना ...)

मैं गृहीत या z- की है कि नियमित रूप प्रतिशतक में अनुकूलित सामान्य चाहते थे स्कोर पर्याप्त नहीं था। कभी-कभी मुझे पता था कि आबादी का अधिकतम अधिकतम और न्यूनतम क्या था, और इसलिए इसे अपने नमूना, या एक अलग मिडपॉइंट, या जो भी हो, के अलावा इसे परिभाषित करना चाहता था! यह अक्सर तंत्रिका जाल के लिए डेटा को पुनर्विक्रय और सामान्य करने के लिए उपयोगी हो सकता है जहां आप 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 से डेटा को स्केल करने की अनुमति देने के लिए (मुझे matplotlib में colormaps संयोजन करते समय ऐसा करना था: Single pcolormesh with more than one colormap using Matplotlib) तो आप देख सकते हैं कि कोड कैसे काम करता है, लेकिन मूल रूप से कहता है कि आपके पास मूल्य हैं [-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] 

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

#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" परिभाषित के सबसे करीब है उच्चतम मूल्य है।

वैसे भी, मैंने सोचा कि मेरा आवेदन प्रासंगिक था यदि आप अन्य तरीकों से डेटा को पुन: सहेजना चाहते हैं जो आपके लिए उपयोगी अनुप्रयोग हो सकता है।

+0

आप सभी if/else कथनों को [कार्यों के साथ शब्दकोश] के साथ प्रतिस्थापित कर सकते हैं (https://stackoverflow.com/questions/60208/replacements-for-switch-statement-in-python)। तब थोड़ा क्लीनर दिखता है। – Roald

+0

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

संबंधित मुद्दे