2013-07-16 29 views
3

如何正常化多指標數據幀?熊貓正常化多指標數據幀

比方說,我有數據幀:

d = pd.DataFrame([["a",1,3],["a",2,2],["b",4,4],["b",5,8]], 
        columns=["name","value1","value2"]) 

我怎麼計算的標準化值對每個「名」?

我知道如何規範基本數據框:

d = (d-d.mean(axis=0))/data.std(axis=0, ddof=1) 

,但我不能夠在每一個「名字」,我的數據框

的應用此所以結果我想要的是:

name, value1, value2 
a  -0.5  0.5 
a  0.5 -0.5 
b  -0.5 -1 
b  0.5  1 

我試圖GROUPBY和多指標數據幀,但可能我沒有做正確的方式

回答

7

按組規範化是one of the examples in the groupby documentation。但它並不完全符合你在這裏想要的。

In [2]: d.groupby('name').transform(lambda x: (x-x.mean())/x.std(ddof=1)) 
Out[2]: 
    value1 value2 
0 -0.707107 0.707107 
1 0.707107 -0.707107 
2 -0.707107 -0.707107 
3 0.707107 0.707107 

你期望的結果表明,你真的想參照value1value2元素正常化每個名稱組中的值。對於這樣的事情,您可以將函數分別應用於每個組,然後重新組合結果。

In [3]: def normalize(group):              
    mean = group.values.ravel().mean() 
    std = group.values.ravel().std(ddof=1) 
    return group.applymap(lambda x: (x - mean)/std) 
    ....: 

In [4]: pd.concat([normalize(group) for _, group in d.set_index('name').groupby(level=0)]) 
Out[4]: 
     value1 value2 
name      
a -1.224745 1.224745 
a  0.000000 0.000000 
b -0.660338 -0.660338 
b -0.132068 1.452744 
+0

顯然'flatten'使數組的副本。 'ravel()'工作原理相同,但沒有副本。 – TomAugspurger

+0

我不知道那個。謝謝! –

+0

謝謝你們兩位!抱歉,由於我的低信譽,我無法贊成!我現在開始更好地理解如何與熊貓一起工作了! – user1883737

0

你確定你給出的結果是正確的嗎?我假設你想分別規範化value1和value2。如果這不正確,請告訴我。

# Easier with `name` as the index. 

In [65]: d = d.set_index('name') 

In [66]: d 
Out[66]: 
     value1 value2 
name     
a   1  3 
a   2  2 
b   4  4 
b   5  8 

In [68]: means = g.mean() 

In [69]: stds = g.std() 

In [70]: means 
Out[70]: 
     value1 value2 
name     
a  1.5  2.5 
b  4.5  6.0 

In [71]: stds 
Out[71]: 
     value1 value2 
name      
a  0.707107 0.707107 
b  0.707107 2.828427 

In [76]: g.transform(lambda x: (x - means)/stds) 
Out[76]: 
     value1 value2 
name      
a -0.707107 0.707107 
a  0.707107 -0.707107 
a   NaN  NaN 
b   NaN  NaN 
b -0.707107 -0.707107 
b  0.707107 0.707107 

# Get rid of the nans 

In [77]: g.transform(lambda x: (x - means)/stds).dropna() 
Out[77]: 
     value1 value2 
name      
a -0.707107 0.707107 
a  0.707107 -0.707107 
b -0.707107 -0.707107 
b  0.707107 0.707107 
+0

對不起,你是正確的,我以錯誤的方式規範化它! 感謝一噸,爲將來的參考,我想你忘了 g = d.groupby(「name」) – user1883737

+0

是的,你說得對。 FWIW,我認爲丹的回答更清潔。 – TomAugspurger