Python NumPy复杂切片
我有一个NumPy数组,例如:Python NumPy复杂切片,python,numpy,slice,Python,Numpy,Slice,我有一个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]]) 是否有方法获取包含第
>>> 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]])
显然,我想要一种通用的方法,它可以有效地处理多维大阵列(不仅仅是上面的玩具示例)。试试:
>>> np.array([x[0, 1:3], x[1, 2:4], x[3, 3:5]])
array([[7, 3],
[5, 7],
[8, 4]])
尝试:
只要行之间的偏移一致,就可以使用:
# 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_brand
功能强大得不可思议,所以在使用时要非常小心。例如,绝对确保视图在最后几行中没有超出边界
如果可以避免,请尽量不要将任何内容分配到所返回的视图中。如果您不确切知道自己在做什么,则赋值只会增加不可预知行为和崩溃的危险数千倍。只要行之间的偏移量一致,您就可以使用:
# 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_brand
功能强大得不可思议,所以在使用时要非常小心。例如,绝对确保视图在最后几行中没有超出边界
如果可以避免,请尽量不要将任何内容分配到所返回的视图中。如果你不确切知道自己在做什么,任务只会增加不可预知的行为和崩溃的危险一千倍
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]
所以你可以根据你的需要修改它。祝你好运 我猜是这样的: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]
所以你可以根据你的需要修改它。祝你好运 我将提取对角线向量并将它们堆叠在一起,如下所示:
def diag_slice(x, start, end):
n_rows = min(*x.shape)-end+1
columns = [x.diagonal(i)[:n_rows, None] for i in range(start, end)]
return np.hstack(columns)
In [37]: diag_slice(x, 1, 3)
Out[37]:
array([[7, 3],
[5, 7],
[3, 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])
我将提取对角线向量并将它们堆叠在一起,如下所示:
def diag_slice(x, start, end):
n_rows = min(*x.shape)-end+1
columns = [x.diagonal(i)[:n_rows, None] for i in range(start, end)]
return np.hstack(columns)
In [37]: diag_slice(x, 1, 3)
Out[37]:
array([[7, 3],
[5, 7],
[3, 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])
在一般情况下,很难击败逐行列表理解:
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])]
如果生成的阵列大小相同,则可以将它们组合成一个二维阵列:
In [30]: np.array(_)
Out[30]:
array([[7, 8],
[2, 0],
[9, 2]])
另一种方法是连接之前的索引。我将不深入讨论细节,但创建如下内容:
def diag_slice(x, start, end):
n_rows = min(*x.shape)-end+1
columns = [x.diagonal(i)[:n_rows, None] for i in range(start, end)]
return np.hstack(columns)
In [37]: diag_slice(x, 1, 3)
Out[37]:
array([[7, 3],
[5, 7],
[3, 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_跨步的技巧可能更快,但需要更多的理解
还提出了一些基于掩蔽的方法。但是细节更复杂,所以我将把这些留给像@Divakar这样专门研究它们的人。对于一般情况,很难击败逐行列表理解:
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])]
如果生成的阵列大小相同,则可以将它们组合成一个二维阵列:
In [30]: np.array(_)
Out[30]:
array([[7, 8],
[2, 0],
[9, 2]])
另一种方法是连接之前的索引。我将不深入讨论细节,但创建如下内容:
def diag_slice(x, start, end):
n_rows = min(*x.shape)-end+1
columns = [x.diagonal(i)[:n_rows, None] for i in range(start, end)]
return np.hstack(columns)
In [37]: diag_slice(x, 1, 3)
Out[37]:
array([[7, 3],
[5, 7],
[3, 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_跨步的技巧可能更快,但需要更多的理解
还提出了一些基于掩蔽的方法。但是细节更复杂,所以我将把这些留给像@Divakar这样专门研究它们的人。有人已经指出了的技巧,是的,你真的应该谨慎使用
这是一种广播/花式索引方法,它的效率不如_大步前进时的
,但在我看来仍然非常有效
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]
有人已经指出了的技巧,是的,你应该谨慎使用
这是一种广播/花式索引方法,它的效率不如_大步前进时的
,但在我看来仍然非常有效
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]
第三排和第五排呢?还有,所有窗户的长度都一样吗?第三排和第五排呢?另外,所有窗口的长度是否相同?请注意,这会通过包装在np.array中生成一个副本;我相信这(可能)是一个没有that@en_Knight这将是一个视图列表。请注意,这将通过包装在np.array中生成一个副本;我相信这(可能)是一个没有that@en_Knight这将是一个视图列表。