2014-11-22 67 views
1

我有一本字典,爲此我要計算所有值zscores。現在我知道如何計算數組的zscore,但不知道如何爲字典執行此操作。有人有一些提示嗎?的Python:計算詞典的所有值zscores

謝謝!

+0

也許你需要它從字典中提取值列表?如果'd'是你的字典,那麼你可以通過調用'd.values()'來做到這一點。 – Thibaut 2014-11-22 19:52:38

+0

我試圖轉換爲值列表,但我不明白如何將它們與原始密鑰一起放回到字典中。 (對不起,如果這不是我的...) – user2783083 2014-11-22 20:09:52

回答

1

以下是純Python,並計算兩者的平均值和標準偏差(假設1個自由度)在一個單一的通。它直接使用詞典理解來計算詞典中的z分數值。

但請注意,根據下面的時序示例,它比使用字典鍵(請參閱下面的zify_scipy)重新壓縮scipy.stats.zscore的結果要慢3倍左右。

from math import sqrt 

def zify(some_dict): 
    arr = some_dict.values() 
    sum_sq = x_bar = 0 
    for i, val in enumerate(arr): 
     x_bar += val 
     sum_sq += val * val 
    n = 1 + i 
    x_bar *= 1.0/n 
    std = sqrt(1.0/i * sum_sq - (float(n)/i) * x_bar * x_bar) 
    return {k:(v - x_bar)/std for k,v in some_dict.iteritems()} 

test = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5, 'f':6} 
print zify(test) 

# {'a': -1.3363062095621223, 'c': -0.26726124191242445, 
# 'b': -0.8017837257372734, 'e': 0.8017837257372734, 
# 'd': 0.26726124191242445, 'f': 1.3363062095621223} 
# compare with scipy.stats.zscore(test.values(), ddof=1) 

使用answer基於scipy.stats.zscore(以下稱爲zify_scipy),我們可以設置一些例子與timeit測試:在IPython的會話

import numpy as np 
from itertools import izip 
from scipy.stats import zscore 

def zify_scipy(d): 
    keys, vals = zip(*d.items()) 
    return dict(zip(keys, zscore(vals, ddof=1))) 

# test cases 
test1 = dict(izip(range(1000), np.random.randn(1000))) 
test2 = dict(izip(range(10000), np.random.randn(10000))) 
test3 = dict(izip(range(100000), np.random.randn(100000))) 

然後,我測試zifyzify_scipy

In [411]: %timeit zify_scipy(test1) 
1000 loops, best of 3: 407 µs per loop 

In [412]: %timeit zify(test1) 
1000 loops, best of 3: 1.42 ms per loop 

In [413]: %timeit zify_scipy(test2) 
100 loops, best of 3: 4.43 ms per loop 

In [414]: %timeit zify(test2) 
100 loops, best of 3: 14.3 ms per loop 

In [415]: %timeit zify_scipy(test3) 
10 loops, best of 3: 58.8 ms per loop 

In [416]: %timeit zify(test3) 
10 loops, best of 3: 144 ms per loop 

一注:無論您是否使用zip(*d.items())技巧來獲得位置匹配的鍵/值數組,而不是首先獲取值,然後使用詞典理解來執行另一次迭代(正如我在實現zify結束時所做的那樣)對於時間似乎並不重要。你將不得不迭代兩次(一次計算平均值/標準差,一次來轉換值)。

對於純Python來說,大概3倍的減速並不是那麼糟糕。對於中等使用情況,我會對此感到滿意,以此來避免對scipy的額外依賴。但對於已經在使用numpy/scipy的項目,請參閱zify_scipy

0

假設使用SciPy的計算Z分數,而不是手動

從SciPy的進口統計

d = { '鍵':值,...}

dict_values = d.values()

Z = stats.zscore(dict_values)

這將返回一個Numpy數組,其z分數爲

+0

謝謝!我如何獲得zscores與相應的鍵一起回來? – user2783083 2014-11-22 20:12:51

+0

你的意思是一個新的字典與相應的鍵?那麼你可以使用字典理解:'new_dict = {(k,v)for(k,v)in zip(d.keys(),z)}'。編輯:請注意,如果你這樣做,最好使用'itertools import izip'而不是普通的'zip' – hopla 2014-11-22 20:20:05

1

假設d是您的字典,並且您需要zscores的值。

import scipy.stats as stats 
keys, vals = zip(*d.items()) 
z = stats.zscore(vals) 
newmap = dict(zip(keys,z)) 
0

所以假設你想計算一個字典中所有值的zscores。並且還假設你知道的平均值和標準偏差

所以,你會根本是什麼迭代在所有的值和zscore存儲在相同的按鍵另一個字典。 可以說,DIC是你的百科

import numpy  
a={} 
for key,value in dic.items(): 
    z=(value-mean)/standarDeviation 
    a[key]=z 

一個將包含所有你zscores,與refernce到相同的密鑰DIC。

如果你不知道先計算平均值和標準偏差爲

mean=numpy.mean(dic.values()) 
standardDeviation= numpy.std(dic.values()) 

dic.values()在你的字典

返回值的列表,但是我會用SciPy的,你可以看到爲什麼。 .. PS這將很好地工作,如果數據集是小,你想看到的數據是如何平移出...