我正在寻找一种方式,即可一次选择从numpy的阵列多个切片。 说,我们有一个一维数据阵列和要提取的其三个部分象下面这样:
data_extractions = []
for start_index in range(0, 3):
data_extractions.append(data[start_index: start_index + 5])
此后data_extractions
将是:
data_extractions = [
data[0:5],
data[1:6],
data[2:7]
]
有没有什么办法没有执行上述操作的循环? 某种索引方案的numpy的,将让我从一个阵列中选择多个片段,并返回它们的许多阵列,说在N + 1个维数组?
我想也许我可以复制我的数据,然后选择从各行的跨度,但下面的代码抛出一个IndexError
replicated_data = np.vstack([data] * 3)
data_extractions = replicated_data[[range(3)], [slice(0, 5), slice(1, 6), slice(2, 7)]
Answer 1:
您可以使用索引来选择您所需的行成合适的形状。 例如:
data = np.random.normal(size=(100,2,2,2))
# Creating an array of row-indexes
indexes = np.array([np.arange(0,5), np.arange(1,6), np.arange(2,7)])
# data[indexes] will return an element of shape (3,5,2,2,2). Converting
# to list happens along axis 0
data_extractions = list(data[indexes])
np.all(data_extractions[1] == s[1:6])
True
Answer 2:
在这篇文章中是与一种方法strided-indexing scheme
使用np.lib.stride_tricks.as_strided
,基本上创建视图到输入阵列,因此是用于创建相当有效且为视图占用曲子的内存空间。 此外,该工程与尺寸的通用号码ndarrays。
这里的实施 -
def strided_axis0(a, L):
# Store the shape and strides info
shp = a.shape
s = a.strides
# Compute length of output array along the first axis
nd0 = shp[0]-L+1
# Setup shape and strides for use with np.lib.stride_tricks.as_strided
# and get (n+1) dim output array
shp_in = (nd0,L)+shp[1:]
strd_in = (s[0],) + s
return np.lib.stride_tricks.as_strided(a, shape=shp_in, strides=strd_in)
对于样品运行4D
阵列的情况下-
In [44]: a = np.random.randint(11,99,(10,4,2,3)) # Array
In [45]: L = 5 # Window length along the first axis
In [46]: out = strided_axis0(a, L)
In [47]: np.allclose(a[0:L], out[0]) # Verify outputs
Out[47]: True
In [48]: np.allclose(a[1:L+1], out[1])
Out[48]: True
In [49]: np.allclose(a[2:L+2], out[2])
Out[49]: True
Answer 3:
stride_tricks
能做到这一点
a = np.arange(10)
b = np.lib.stride_tricks.as_strided(a, (3, 5), 2 * a.strides)
b
# array([[0, 1, 2, 3, 4],
# [1, 2, 3, 4, 5],
# [2, 3, 4, 5, 6]])
请注意, b
引用相同的存储器中作为a
,多次实际上(例如b[0, 1]
和b[1, 0]
是相同的存储器地址)。 因此,它是最安全的新结构的工作之前进行复制。
ND可以以类似的方式来完成,例如2D - > 4D
a = np.arange(16).reshape(4, 4)
b = np.lib.stride_tricks.as_strided(a, (3,3,2,2), 2*a.strides)
b.reshape(9,2,2) # this forces a copy
# array([[[ 0, 1],
# [ 4, 5]],
# [[ 1, 2],
# [ 5, 6]],
# [[ 2, 3],
# [ 6, 7]],
# [[ 4, 5],
# [ 8, 9]],
# [[ 5, 6],
# [ 9, 10]],
# [[ 6, 7],
# [10, 11]],
# [[ 8, 9],
# [12, 13]],
# [[ 9, 10],
# [13, 14]],
# [[10, 11],
# [14, 15]]])
Answer 4:
你可以用事先准备好的切片阵列切片的阵列
a = np.array(list('abcdefg'))
b = np.array([
[0, 1, 2, 3, 4],
[1, 2, 3, 4, 5],
[2, 3, 4, 5, 6]
])
a[b]
然而, b
不必用手以这种方式产生的。 它可以与更多动态
b = np.arange(5) + np.arange(3)[:, None]
Answer 5:
在一般情况下,你必须做一些重复的 - 和串联 - 无论是构建索引或收集结果时的时候。 只有当切片模式本身是正规,你可以通过使用一个通用切片as_strided
。
接受的答案构建一个索引数组,每个切片一行。 所以这是遍历片, arange
本身是一个(快)迭代。 而np.array
连接它们的新轴( np.stack
推广了这一点)。
In [264]: np.array([np.arange(0,5), np.arange(1,6), np.arange(2,7)])
Out[264]:
array([[0, 1, 2, 3, 4],
[1, 2, 3, 4, 5],
[2, 3, 4, 5, 6]])
indexing_tricks
方便的方法做同样的事情:
In [265]: np.r_[0:5, 1:6, 2:7]
Out[265]: array([0, 1, 2, 3, 4, 1, 2, 3, 4, 5, 2, 3, 4, 5, 6])
这需要切片符号,以扩大其arange
并连接。 它甚至让我扩大并连接成2D
In [269]: np.r_['0,2',0:5, 1:6, 2:7]
Out[269]:
array([[0, 1, 2, 3, 4],
[1, 2, 3, 4, 5],
[2, 3, 4, 5, 6]])
In [270]: data=np.array(list('abcdefghijk'))
In [272]: data[np.r_['0,2',0:5, 1:6, 2:7]]
Out[272]:
array([['a', 'b', 'c', 'd', 'e'],
['b', 'c', 'd', 'e', 'f'],
['c', 'd', 'e', 'f', 'g']],
dtype='<U1')
In [273]: data[np.r_[0:5, 1:6, 2:7]]
Out[273]:
array(['a', 'b', 'c', 'd', 'e', 'b', 'c', 'd', 'e', 'f', 'c', 'd', 'e',
'f', 'g'],
dtype='<U1')
拼接后的结果,编制索引还有效。
In [274]: np.stack([data[0:5],data[1:6],data[2:7]])
从其他SO问题,我的内存是相对时间是在大小相同的顺序。 它可以例如与切片与它们的长度的数目而变化。 整体必须被从源复制到目标将是相同的值的数目。
如果切片,长短不一,你必须使用平面索引。
Answer 6:
我们可以使用列表理解这个
data=np.array([1,2,3,4,5,6,7,8,9,10])
data_extractions=[data[b:b+5] for b in [1,2,3,4,5]]
data_extractions
结果
[array([2, 3, 4, 5, 6]), array([3, 4, 5, 6, 7]), array([4, 5, 6, 7, 8]), array([5, 6, 7, 8, 9]), array([ 6, 7, 8, 9, 10])]
文章来源: Selecting multiple slices from a numpy array at once