Numpy -通过跳过循环索引



给定任意长度的np.arange()数组,例如x = np.arange(10),如何有效地生成一个输出数组,跳过从0n的所有n值?

带有当前方法和输出的示例代码:

def circ(arr, n):
y = np.array([])
for i in range(n):
y = np.concatenate((y, arr[i::n]))
return y.astype(int)
for i in range(1,6):
circ(x, i)
"""
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
array([0, 2, 4, 6, 8, 1, 3, 5, 7, 9])
array([0, 3, 6, 9, 1, 4, 7, 2, 5, 8])
array([0, 4, 8, 1, 5, 9, 2, 6, 3, 7])
array([0, 5, 1, 6, 2, 7, 3, 8, 4, 9])
"""

只使用mod很容易,但请注意,对于case4,一旦列表通过跳过每4个元素来耗尽所有累积3个元素的方法,它就会累积2个元素。

我考虑了一种填充、调整大小、平坦和丢弃类型,但我不确定最后丢弃填充值的好方法:

def circ2(arr, n):
arr2 = np.zeros(n*math.ceil(len(arr)/n))
arr2[:len(arr)] = arr
arr3 = np.resize(arr2, (len(arr2)//n, n))
return arr3.T.ravel()
for i in range(1,5):
circ2(x, i)
"""
array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
array([0., 2., 4., 6., 8., 1., 3., 5., 7., 9.])
array([0., 3., 6., 9., 1., 4., 7., 0., 2., 5., 8., 0.])
array([0., 4., 8., 1., 5., 9., 2., 6., 0., 3., 7., 0.])
"""

for循环方法是有效的,但是对于较大的数组(多达5000个元素),它的效率非常低。有没有人知道一个函数,或者有让它更快的见解,或者一个不同的方法?

重复连接是低效的,因为你必须一次又一次地创建一个新的数组。

使用单个连接的循环应该更有效:

x = np.arange(10)
n = 4
out = np.concatenate([x[i::n] for i in range(n)])

输出:

array([0, 4, 8, 1, 5, 9, 2, 6, 3, 7])

作为函数:

def circ2(arr, n):
return np.concatenate([arr[i::n] for i in range(n)])

在1M项的输入数组上执行n in range(1, 6)循环的计时:

# your approach
110 ms ± 4.42 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
# the single concatenate
17.7 ms ± 540 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

最新更新