Python:计算字典到z分数的所有值

时间:2014-11-22 19:51:34

标签: python dictionary statistics

我有一本字典,我想为zscores计算所有值。现在我知道如何计算数组的zscore,但不知道如何为字典执行此操作。有人有提示吗?

谢谢!

4 个答案:

答案 0 :(得分:1)

假设d是你的字典,你想要zscores的值。

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

答案 1 :(得分:1)

以下是纯Python,并在一次通过中计算均值和标准差(假设1个自由度)。它直接用字典理解计算字典中的z得分值。

但请注意,根据下面的时序示例,它比使用dict键重新压缩scipy.stats.zscore的结果慢约3倍(请参阅下面的zify_scipy)。

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)

使用基于scipy.stats.zscore的{​​{3}}(下面称为zify_scipy),我们可以设置一些示例以使用timeit进行测试:

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)))

然后在IPython会话中,我针对zify测试了zify_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())技巧获取位置匹配的键/值数组,而不是先获取值,然后使用dict理解执行另一次迭代(就像我在结束时所做的那样)我的实施zify)似乎并不重要。您将不得不两次迭代(一次计算均值/标准,一次转换值)。

纯Python的大约3倍减速并不是那么糟糕。对于中型用例,我觉得这是一种避免额外依赖scipy的方法。但对于已经使用numpy / scipy的项目,请转到zify_scipy

答案 2 :(得分:0)

假设您使用Scipy来计算Z得分而不是手动

  

来自scipy import stats

     

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

     

dict_values = d.values()

     

z = stats.zscore(dict_values)

这将返回带有z分数的Numpy数组

答案 3 :(得分:0)

因此,假设您想要计算字典中所有值的zscores。并假设您知道平均值和标准差

所以你要做的就是迭代所有值并将zscore存储在另一个具有相同键的字典中。 让我们说dic是你的词典

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

a将包含所有zscores,并引用与dic中相同的键。

如果您不知道首先计算平均值和标准差为

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

dic.values()返回词典中的值列表

但是我会使用scipy,你可以看到为什么...... 附:如果数据集很小,那么这将很有效,并且您希望看到数据如何平移......