Python/Numpy - 将切片循环到数组末尾

6

我有两个一维数组,一个包含一些感兴趣的值(a),另一个提供了对该数组的索引(b)。我知道b中的值始终在增加,除了一个点(可能在任何位置)会减少,因为它从数组a的末尾滚动到开头。下面的方法似乎有效,但我认为必须存在一种更简洁的方法。有人能提出更好的建议吗?谢谢。

代码:

import numpy as np
a = np.arange(12)
b = np.array([5, 9, 2, 4])
#I want to generate these:
#[5,6,7,8,9]
#[9,10,11,0,1,2]
#[2,3,4]
#[4,5]

a = np.roll(a, -b[0], axis=0)
# Subtract off b[0] but ensure that all values are positive
b = (b-b[0]+len(a))%len(a)
for i, ind in enumerate(b):
   if i < len(b)-1:
      print a[b[i]:b[i+1]+1]
   else:
      print np.hstack((a[b[i]:len(a)], a[0]))
2个回答

3
有点短,但也许我还能做得更好...
import numpy as np

a = np.arange(12)
b = np.array([5, 9, 2, 4])
b = np.append(b, b[0])

for i in range(0, len(b)-1):
    print np.roll(a, len(a)-b[i])[:b[i+1]-b[i]+1]

你可以使用以下代码使其更简洁:np.roll(a,-b[i])[:b[i+1]-b[i]+1] - JoshAdel
1
谢谢,这样更简洁了。虽然它可能会调用roll函数多次,我认为对于非常大的数组来说,这可能会减慢速度。你能想到不使用roll的方法吗?将你的np.roll(...行替换为简单的a[b[i]:b[i+1]+1]将适用于除了那个滚动发生的情况之外的所有情况。 - Scott B
你可以将整个数组a附加到它本身,并重新计算a[start:end]的索引,但我认为这会更加复杂,而不是更简单。我相信有一种使用步幅来完成这个任务的方法,只是我还没有时间去尝试... - Benjamin
我在想这也可以用步幅来完成。但是我对它们并不了解。如果我有时间,我会尝试更深入地研究它们。 - Scott B

1

不确定这是否有帮助,但是一种快速的方法而不会干扰a的内存是这样的:

import numpy as np

a = np.arange(12)
b = np.array([5, 9, 2, 4])
b = np.append(b, b[0])

b2 = b.copy()

b2[(np.diff(b)<0).nonzero()[0]+1:] += a.size

print [np.take(a, np.r_[b2[i]:b2[i+1]+1], mode='wrap') for i in range(b.size-1)]

print [np.roll(a, len(a)-b[i])[:b[i+1]-b[i]+1] for i in range(b.size-1)]

%timeit [np.take(a, np.r_[b2[i]:b2[i+1]+1], mode='wrap') for i in range(b.size-1)]
# 10000 loops, best of 3: 28.6 µs per loop

%timeit [np.roll(a, len(a)-b[i])[:b[i+1]-b[i]+1] for i in range(b.size-1)]
# 10000 loops, best of 3: 77.7 µs per loop

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接