Python中索引对(或多个)求和
计算样本基尼系数的一种方法是使用相对平均差(RMD),它是基尼系数的2倍。RMD取决于平均差,平均差由下式给出: 因此,我需要计算示例Python中索引对(或多个)求和,python,numpy,sum,Python,Numpy,Sum,计算样本基尼系数的一种方法是使用相对平均差(RMD),它是基尼系数的2倍。RMD取决于平均差,平均差由下式给出: 因此,我需要计算示例(yi-yj)中元素对之间的每个差异。我花了相当多的时间才想出一种方法,但我想知道是否有一个函数可以为您实现这一点 起初我尝试过这个方法,但我打赌在大数据集中速度非常慢(顺便说一下,s是示例): 然后我尝试了以下不太容易理解但更快的方法: In [126]: %%timeit m = abs(s - s.reshape(len(s), 1)) MD = np.s
(yi-yj)
中元素对之间的每个差异。我花了相当多的时间才想出一种方法,但我想知道是否有一个函数可以为您实现这一点
起初我尝试过这个方法,但我打赌在大数据集中速度非常慢(顺便说一下,s是示例):
然后我尝试了以下不太容易理解但更快的方法:
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
有什么有效但易于推广的方法吗?例如,如果我想对三个指数求和怎么办
这是我使用的示例:
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
谢谢 对于您给出的MD示例,可以通过排序利用它,您可以实现O(N*Log(N))而不是O(N^2)
通常,您必须使用动态规划或其他技术来加快计算速度,我不确定是否有“一种方法适合所有人”的解决方案。您的问题是“我想要一种有效的方法来计算MD,因为给出了MD的公式”不是真的。MD只是一个激发我的问题的例子。这更像是“我想要一种有效且易于理解的方法来对索引求和”。@RobertSmith您能提供一个示例,以便我可以将我的代码结果与您的代码结果进行比较吗?当然。给我几秒钟,我加了一个样品。请参阅我的更新。实际上,您的fast函数比[126]中的速度慢208倍(直到计算MD为止)。很可能,一个好的解决方案需要避免任何循环。嗯,样本有多大?通过我的测试,使用fast()方法,大样本的速度要快得多。事实上,似乎整形()甚至不能在大于10^4的样本上运行,而我的在小于10^6的样本上运行不到一秒钟。对于小样本,由于函数调用等的开销,您的方法可能会更快。对于小样本,我展示的第二个代码速度更快,但对于大样本,它变得慢得让人无法忍受,这与你的代码速度相当快不同,因为你正在使用一种技巧,认识到原始和可以表示为乘法和。你知道如何扩展这个结果来考虑更多的指数吗?我会有一个想法。可能通过包含排除或二元或三元搜索。因此,如果是yi+yj-yk,则可以排序,然后对每个k进行遍历,并为最小yi和最大yj设置一个滚动区间,该区间的总和大于yk。这表明yk贡献了多少。我想对于更高的维度也是如此。此外,你可能有兴趣阅读这个答案,这是非常弱的相关性
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
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)