在Python中总结一对索引(或更多)

Rob*_*ith 10 python numpy sum

计算样本基尼系数的一种方法是使用相对平均差(RMD),它是基尼系数的2倍.RMD取决于以下给出的平均差异:

在此输入图像描述

所以我需要计算样本中元素对之间的每个差异(yi - yj).我花了很多时间想出办法,但我想知道是否有一个功能可以帮到你.

起初我试过这个,但我敢打赌它在大数据集中非常慢(顺便说一下,s是样本):

In [124]:

%%timeit
from itertools import permutations
k = 0
for i, j in list(permutations(s,2)):
    k += abs(i-j)
MD = k/float(len(s)**2)
G = MD / float(mean(s))
G = G/2
G
10000 loops, best of 3: 78 us per loop
Run Code Online (Sandbox Code Playgroud)

然后我尝试了以下哪个不太容易理解但更快:

In [126]:
%%timeit
m = abs(s - s.reshape(len(s), 1))
MD = np.sum(m)/float((len(s)**2))
G = MD / float(mean(s))
G = G/2
G
10000 loops, best of 3: 46.8 us per loop
Run Code Online (Sandbox Code Playgroud)

有没有什么有效但容易概括的东西?例如,如果我想总结三个指数怎么办?

这是我使用的样本:

sample = array([5487574374,     686306,    5092789,   17264231,   41733014,
         60870152,   82204091,  227787612,  264942911,  716909668,
        679759369, 1336605253,  788028471,  331434695,  146295398,
         88673463,  224589748,  128576176,  346121028])

gini(sample)
Out[155]:
0.2692307692307692
Run Code Online (Sandbox Code Playgroud)

谢谢!

rob*_*ing 1

对于您给出的 MD 示例,可以通过排序来利用它,您可以实现 O(N*Log(N)) 而不是 O(N^2)

y = [2,3,2,34]

def slow(y):
    tot = 0
    for i in range(len(y)):
        for j in range(len(y)):
            if i != j:
                tot += abs(y[i] - y[j])
    return float(tot)/len(y)**2

print slow(y)

def fast(y):
    sorted_y = sorted(y)
    tot = 0
    for i, yi in enumerate(sorted_y):
        smaller = i
        bigger = len(y) - i - 1
        tot += smaller * yi - bigger * yi
    return float(2*tot)/len(y)**2

print fast(y)
Run Code Online (Sandbox Code Playgroud)

通常,您必须使用动态编程或其他技术来使这些更快,我不确定是否存在“一种方法适合所有”的解决方案。