我知道这个问题已经回答了很多次,因此我就此主题回答了每个SO问题,但是似乎没有一个问题可以解决我的问题。
此代码产生一个异常:
TypeError: only integer scalar arrays can be converted to a scalar index
a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
sindex = np.array([0, 3, 4])
eindex = np.array([2, 5, 6])
r = a[sindex: eindex]
我有一个包含开始索引的数组,另一个包含结束索引的数组,我只是想提取它们之间的任何内容。请注意,sindex和eindex之间的差异是恒定的,例如2。因此,eindex始终是sindex + 2中的值。
所以预期结果应该是:
[1, 2, 4, 5, 5, 6]
有没有没有for循环的方法?
答案 0 :(得分:2)
对于恒定的间隔差,我们可以设置滑动窗口,并简单地使用起始索引数组进行索引。因此,我们可以使用this post
-
broadcasting_app
或strided_app
d = 2 # interval difference
out = broadcasting_app(a, L = d, S = 1)[sindex].ravel()
out = strided_app(a, L = d, S = 1)[sindex].ravel()
或使用scikit-image's
built-in view_as_windows
-
from skimage.util.shape import view_as_windows
out = view_as_windows(a,d)[sindex].ravel()
要设置d
,我们可以使用-
d = eindex[0] - sindex[0]
答案 1 :(得分:1)
您不能告诉编译后的numpy
直接获取多个切片。连接多个切片的替代方法涉及某种高级索引。
In [509]: a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
...:
...: sindex = np.array([0, 3, 4])
...: eindex = np.array([2, 5, 6])
最明显的循环:
In [511]: np.hstack([a[i:j] for i,j in zip(sindex, eindex)])
Out[511]: array([1, 2, 4, 5, 5, 6])
使用循环首先构造索引的变体:
In [516]: a[np.hstack([np.arange(i,j) for i,j in zip(sindex, eindex)])]
Out[516]: array([1, 2, 4, 5, 5, 6])
由于切片的大小都相同,我们可以生成一个arange
并使用sindex
进行步进:
In [521]: a[np.arange(eindex[0]-sindex[0]) + sindex[:,None]]
Out[521]:
array([[1, 2],
[4, 5],
[5, 6]])
,然后ravel
。这是@Divakar's
broadcasting_app`的更直接表达。
在这个小例子中,时序相似。
In [532]: timeit np.hstack([a[i:j] for i,j in zip(sindex, eindex)])
13.4 µs ± 257 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [533]: timeit a[np.hstack([np.arange(i,j) for i,j in zip(sindex, eindex)])]
21.2 µs ± 362 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [534]: timeit a[np.arange(eindex[0]-sindex[0])+sindex[:,None]].ravel()
10.1 µs ± 48.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [535]: timeit strided_app(a, L=2, S=1)[sindex].ravel()
21.8 µs ± 207 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
strided_app
和view_as_windows
使用步进技巧将数组视为大小为d
的窗口数组,并使用sindex
选择其中的一个子集。
在较大的情况下,相对时间可能会随着切片的大小与切片的数量而变化。
答案 2 :(得分:0)