Python Numpy:与列相关的切片

Python Numpy:与列相关的切片,python,numpy,Python,Numpy,我找不到任何关于我想做什么的问题,所以我现在问。基本上,我想要在矩阵中切片,其中行索引取决于列索引 例如: >>> import numpy as np >>> x = np.arange(24).reshape(6,4) >>> x array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11], [12, 13, 14, 15],

我找不到任何关于我想做什么的问题,所以我现在问。基本上,我想要在矩阵中切片,其中行索引取决于列索引

例如:

>>> import numpy as np
>>> x = np.arange(24).reshape(6,4)
>>> x
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15],
       [16, 17, 18, 19],
       [20, 21, 22, 23]])
现在我需要的是:

array([[12,  9,  6,  3],
       [16, 13, 10,  7],
       [20, 17, 14, 11]])
所以我有一组给定的(固定的)列索引。行索引依赖于它们。例如:
row=col-1:col+1


有没有一种有效的方法?我知道我可以从每一列中迭代和切片我需要的条目,但这对我来说效率很低。

您可以使用
来执行此操作:

In [1]: from numpy.lib.stride_tricks import as_strided
In [2]: sz = x.itemsize
In [3]: d = as_strided(x[-1::-1,:], shape=(3,4), strides=sz*np.array([-4,-3]))
In [4]: d
Out[5]: 
array([[20, 17, 14, 11],
       [16, 13, 10,  7],
       [12,  9,  6,  3]])
也就是说,从原始数组倒置开始,通过向后跨4个项目(第一个坐标为4个项目,第二个坐标为3个项目)填充3x4数组

如果需要,您可以倒过来查看
d

In [6]: d[-1::-1,:]    # or np.flipud(d)
Out[6]: 
array([[12,  9,  6,  3],
       [16, 13, 10,  7],
       [20, 17, 14, 11]])

您可以按步骤使用
来执行此操作:

In [1]: from numpy.lib.stride_tricks import as_strided
In [2]: sz = x.itemsize
In [3]: d = as_strided(x[-1::-1,:], shape=(3,4), strides=sz*np.array([-4,-3]))
In [4]: d
Out[5]: 
array([[20, 17, 14, 11],
       [16, 13, 10,  7],
       [12,  9,  6,  3]])
也就是说,从原始数组倒置开始,通过向后跨4个项目(第一个坐标为4个项目,第二个坐标为3个项目)填充3x4数组

如果需要,您可以倒过来查看
d

In [6]: d[-1::-1,:]    # or np.flipud(d)
Out[6]: 
array([[12,  9,  6,  3],
       [16, 13, 10,  7],
       [20, 17, 14, 11]])

我本来打算在评论中留下一个基于
对角线的
解决方案,但在时间测试中,它被证明比
跨步的
解决方案更快

In [128]: timeit d = as_strided(x[::-1,:], shape=(3,4),
     strides=sz*np.array([-4,-3]))[::-1,:]
10000 loops, best of 3: 44 µs per loop

In [129]: timeit np.array([x[::-1,:].diagonal(i) for i in [-2,-1,0]])
10000 loops, best of 3: 25.9 µs per loop
对于较大的
x
,这可能不是真的。但是
对角
解决方案的优点是它可能更容易理解


对于
(69,40)
x

np.array([x[::-1,:].diagonal(i) for i in range(-(n-1),1)])
生成一个
(30,40)
数组,该数组包含所有长度的40条反向对角线

解决方案是:

as_strided(x[::-1,:], shape=(n,m), strides=-sz*np.array([m,m-1]))[::-1,:]

弄清楚如何调整这些值以产生正确的步幅并不容易。但是速度更快。时间与较小数组的时间基本相同,而
对角线
方法随着大小而变慢。

我打算在注释中留下一个基于
对角线
的解决方案,但在时间测试中,它被证明比
跨步
方法更快

In [128]: timeit d = as_strided(x[::-1,:], shape=(3,4),
     strides=sz*np.array([-4,-3]))[::-1,:]
10000 loops, best of 3: 44 µs per loop

In [129]: timeit np.array([x[::-1,:].diagonal(i) for i in [-2,-1,0]])
10000 loops, best of 3: 25.9 µs per loop
对于较大的
x
,这可能不是真的。但是
对角
解决方案的优点是它可能更容易理解


对于
(69,40)
x

np.array([x[::-1,:].diagonal(i) for i in range(-(n-1),1)])
生成一个
(30,40)
数组,该数组包含所有长度的40条反向对角线

解决方案是:

as_strided(x[::-1,:], shape=(n,m), strides=-sz*np.array([m,m-1]))[::-1,:]

弄清楚如何调整这些值以产生正确的步幅并不容易。但是速度更快。时间与较小数组的时间基本相同,而
对角
方法会随着大小而变慢。

您可以使用
np.diag
np.rot90
以及
np.transpose
的组合来构建时间。将此保留为注释,因为我不知道如何进行您要求的精确提取。对角线解决方案:
np.array([x[:-1,:].diagonal(I)表示[-2,-1,0]])
。由于
np.diaggal
不需要列表,因此它确实涉及到输出的每一行上的交互。您可以将
np.diag
np.rot90
以及可能的
np.transpose
组合起来构建它。将此保留为注释,因为我不知道如何进行您要求的精确提取。对角线解决方案:
np.array([x[:-1,:].diagonal(I)表示[-2,-1,0]])
。它确实涉及到在输出的每一行上的交互,因为
np。对角线不接受列表。