Python/Numpy - 在数组末尾环绕切片

Posted

技术标签:

【中文标题】Python/Numpy - 在数组末尾环绕切片【英文标题】:Python/Numpy - Wrap Slice Around End of Array 【发布时间】:2011-08-06 17:36:26 【问题描述】:

我有两个一维数组,一个具有一些感兴趣的值 (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]))

【问题讨论】:

【参考方案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

【讨论】:

【参考方案2】:

有点短,但也许我还能做得更好……

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] 让它更干净一些 谢谢,这更干净了。尽管它可能对 roll 函数有更多调用,但我认为这可能会减慢非常大的数组的速度。你能想到不使用滚动来做到这一点吗?用简单的a[b[i]:b[i+1]+1] 替换您的np.roll(... 行将适用于除发生翻转的情况之外的所有情况。 您可以将整个数组 a 附加到自身,并重新计算 a[start:end] 的索引,但我认为这会更复杂,而不是更少。我确信有一种方法可以大踏步地做到这一点,只是还没有时间尝试...... 我在想也可以大步前进。虽然我一点也不了解他们。如果我有时间,我会尝试更多地调查他们。

以上是关于Python/Numpy - 在数组末尾环绕切片的主要内容,如果未能解决你的问题,请参考以下文章

乐哥学AI_Python:Numpy索引,切片,常用函数

Python列表/数组:禁用切片中的负索引环绕

python数据分析 python numpy--数组--运算,切片和索引

python numpy

Go 切片内存分配

python numpy查询数组是不是有某个数的总个数