我有一个NumPy数组,例如:
>>> import numpy as np
>>> x = np.random.randint(0, 10, size=(5, 5))
>>> x
array([[4, 7, 3, 7, 6],
[7, 9, 5, 7, 8],
[3, 1, 6, 3, 2],
[9, 2, 3, 8, 4],
[0, 9, 9, 0, 4]])
是否有一种方法来获取包含第一行的索引1:3
,第二行的索引2:4
和第四行的索引3:5
的视图(或副本)?
因此,在上面的示例中,我希望获得:
>>> # What to write here?
array([[7, 3],
[5, 7],
[8, 4]])
很显然,我希望有一种通用方法也可以对多维大数组有效(并且不仅适用于上面的玩具示例)。
答案 0 :(得分:2)
尝试:
>>> np.array([x[0, 1:3], x[1, 2:4], x[3, 3:5]])
array([[7, 3],
[5, 7],
[8, 4]])
答案 1 :(得分:2)
只要行之间的偏移量是均匀的,就可以使用numpy.lib.stride_tricks.as_strided
:
# How far to step along the rows
offset = 1
# How wide the chunk of each row is
width = 2
view = np.lib.stride_tricks.as_strided(x, shape=(x.shape[0], width), strides=(x.strides[0] + offset * x.strides[1],) + x.strides[1:])
保证结果是原始数据的视图,而不是副本。
由于as_strided
功能强大,因此请务必谨慎使用。例如,绝对确保视图在最后几行中不会超出范围。
如果可以避免,请尽量不要在as_strided
返回的视图中分配任何内容。如果您不确切地知道自己在做什么,那么分配只会增加行为无法预测的危险,并且崩溃的危险会翻倍。
答案 2 :(得分:0)
我猜是这样的:D
In:
import numpy as np
x = np.random.randint(0, 10, size=(5, 5))
Out:
array([[7, 3, 3, 1, 9],
[6, 1, 3, 8, 7],
[0, 2, 2, 8, 4],
[8, 8, 1, 8, 8],
[1, 2, 4, 3, 4]])
In:
list_of_indicies = [[0,1,3], [1,2,4], [3,3,5]] #[row, start, stop]
def func(array, row, start, stop):
return array[row, start:stop]
for i in range(len(list_of_indicies)):
print(func(x,list_of_indicies[i][0],list_of_indicies[i][1], list_of_indicies[i][2]))
Out:
[3 3]
[3 8]
[3 4]
因此您可以根据需要进行修改。祝你好运!
答案 3 :(得分:0)
我将提取对角矢量并将它们堆叠在一起,就像这样:
''
答案 4 :(得分:0)
在一般情况下,很难逐行理解:
In [28]: idx = np.array([[0,1,3],[1,2,4],[4,3,5]])
In [29]: [x[i,j:k] for i,j,k in idx]
Out[29]: [array([7, 8]), array([2, 0]), array([9, 2])]
如果结果数组的大小都相同,则可以将它们合并为一个2d数组:
In [30]: np.array(_)
Out[30]:
array([[7, 8],
[2, 0],
[9, 2]])
另一种方法是在之前连接索引。我不会详细介绍,但创建类似这样的内容:
In [27]: x[[0,0,1,1,3,3],[1,2,2,3,3,4]]
Out[27]: array([7, 8, 2, 0, 3, 8])
从不同的行中选择会使第二种方法复杂化。从概念上讲,第一个更简单。过去的经验表明,速度大致相同。
对于均匀长度的切片,诸如as_strided技巧之类的方法可能更快,但是需要更多的了解。
还提出了一些基于掩蔽的方法。但是细节更加复杂,因此我将把那些留给像@Divakar这样专门从事这些工作的人处理。
答案 5 :(得分:0)
有人已经指出了as_strided
的窍门,是的,您应该谨慎使用它。
这是一种广播/花式索引方法,效率不如as_strided
,但在IMO上仍然运行良好
window_size, step_size = 2, 1
# index within window
index = np.arange(2)
# offset
offset = np.arange(1, 4, step_size)
# for your case it's [0, 1, 3], I'm not sure how to generalize it without further information
fancy_row = np.array([0, 1, 3]).reshape(-1, 1)
# array([[1, 2],
# [2, 3],
# [3, 4]])
fancy_col = offset.reshape(-1, 1) + index
x[fancy_row, fancy_col]