假设我有以下Numpy数组,其中我只有一个1
的连续切片:
import numpy as np
x = np.array([0,0,0,0,1,1,1,0,0,0], dtype=1)
我希望找到1
元素的1D质心的索引。我可以输入以下内容:
idx = np.where( x )[0]
idx_center_of_mass = int(0.5*(idx.max() + idx.min()))
# this would give 5
(当1
s切片的元素数是偶数时,这会导致粗略的近似。)
有没有更好的方法来做到这一点,比如计算效率更高的oneliner?
答案 0 :(得分:3)
您不能简单地执行以下操作吗?
center_of_mass = (x*np.arange(len(x))).sum()/x.sum() # 5
%timeit center_of_mass = (x*arange(len(x))).sum()/x.sum()
# 100000 loops, best of 3: 10.4 µs per loop
答案 1 :(得分:2)
作为一种方法,我们可以获得非零指数并得到那些作为质心的平均值,如此 -
np.flatnonzero(x).mean()
这是另一种方法,使用移位数组比较来获得该切片的起始和停止指数,并获得用于确定质心的那些指数的平均值,如下所示 -
np.flatnonzero(x[:-1] != x[1:]).mean()+0.5
运行时测试 -
In [72]: x = np.zeros(10000,dtype=int)
In [73]: x[100:2000] = 1
In [74]: %timeit np.flatnonzero(x).mean()
10000 loops, best of 3: 115 µs per loop
In [75]: %timeit np.flatnonzero(x[:-1] != x[1:]).mean()+0.5
10000 loops, best of 3: 38.7 µs per loop
我们可以使用np.nonzero()[0]
替换np.flatnonzero
和np.sum
取代np.mean
-
In [107]: %timeit (np.nonzero(x[:-1] != x[1:])[0].sum()+1)/2.0
10000 loops, best of 3: 30.6 µs per loop
或者,对于第二种方法,我们可以存储起始和停止索引,然后简单地添加它们以获得质量中心以获得更有效的方法,因为我们将避免对np.mean
的函数调用,如所以 -
start,stop = np.flatnonzero(x[:-1] != x[1:])
out = (stop + start + 1)/2.0
计时 -
In [90]: %timeit start,stop = np.flatnonzero(x[:-1] != x[1:])
10000 loops, best of 3: 21.3 µs per loop
In [91]: %timeit (stop + start + 1)/2.0
100000 loops, best of 3: 4.45 µs per loop
同样,我们可以在这里试验np.nonzero()[0]
。