2014-11-22 54 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这将很好地工作,如果数据集是小,你想看到的数据是如何平移出...