python - 有效计算数组元素的所有成对组合的度量

标签 python numpy combinatorics

我有以下代码,其中计算数组元素之间的平均差。有没有办法比嵌套循环(如 numpy 函数)更有效地执行此操作?

import numpy as np

a = np.array([0.02625, -0.04125, -0.00875, -0.05625, 0.04375, 0.03625])

delta = []
for i in range(len(a) - 1):
  for j in range(i+1, len(a)):
    delta.append(a[i] - a[j])    
delta = np.array(delta)

avg_dist = np.sum(np.abs(delta)) / delta.size

最佳答案

方法#1

使用 np.triu_indices 获取成对索引/np.tril_indices ,使用它们对输入数组进行索引,从而计算差异 -

I,J = np.triu_indices(len(a),1)
delta = a[I] - a[J]

方法#2

我们还可以在一个循环中使用切片,这应该是内存高效的,因为它避免了生成索引,如前一种方法中所做的那样 -

def pairwise_diff(a):
    n = len(a)
    N = n*(n-1)//2
    idx = np.concatenate(( [0], np.arange(n-1,0,-1).cumsum() ))
    start, stop = idx[:-1], idx[1:]
    out = np.empty(N,dtype=a.dtype)
    for j,i in enumerate(range(n-1)):
        out[start[j]:stop[j]] = a[i,None] - a[i+1:]
    return out

具有 10000 元素的大型数组的计时 -

In [214]: a = np.random.rand(10000)

# Approach #1
In [215]: %%timeit
     ...: I,J = np.triu_indices(len(a),1)
     ...: delta = a[I] - a[J]
1 loop, best of 3: 627 ms per loop

# Approach #2
In [216]: %timeit pairwise_diff(a)
10 loops, best of 3: 69.1 ms per loop

# Original approach
In [217]: %%timeit
     ...: delta = []
     ...: for i in range(len(a) - 1):
     ...:   for j in range(i+1, len(a)):
     ...:     delta.append(a[i] - a[j])
1 loop, best of 3: 15.7 s per loop

关于python - 有效计算数组元素的所有成对组合的度量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49883359/

相关文章:

python - Django: 'Settings' 对象没有属性

python - 推特/ Facebook 评论分类为各种类别

python - 通过使用二维数组索引来填充 numpy 数组

java - 没有重复和顺序的动态规划/组合并不重要

algorithm - 从 N 生成长度为 K 的所有无序排列的快速算法

python - (list|set|dict) 包含 yield 表达式的理解不返回 (list|set|dict)

python slice() 函数 vs slice notation - 如何处理 slice() 中的空值?

python - 如何从 numpy 数组中提取满足多个条件的行?

Python:两个列表之间的快速映射和查找