Python 更改numpy数组的步长(更改数据)

Python 更改numpy数组的步长(更改数据),python,arrays,numpy,Python,Arrays,Numpy,我有一个numpy数组,我想更改它的步长,同时修改它的数据,以便新数组描述相同的数字逻辑对齐。有办法吗 BACKGROUND:我用cv2.imdecode()读取了一个图像文件,该文件生成的BGR图像的最低阶步长设置为3(因此不同像素的通道之间没有间隙)。我想用cairo软件包修改这个图像,它想使用Stride4(也就是说,两个连续像素之间有一个字节的间隔)。哪种方法最好?(我也希望尽可能地优化,因为我必须多次这样做)。假设输入数组是(n,m,3),那么它可以通过简单地连接(n,m,4)数组扩展

我有一个numpy数组,我想更改它的
步长
,同时修改它的数据,以便新数组描述相同的数字逻辑对齐。有办法吗


BACKGROUND:我用
cv2.imdecode()
读取了一个图像文件,该文件生成的BGR图像的最低阶步长设置为3(因此不同像素的通道之间没有间隙)。我想用
cairo
软件包修改这个图像,它想使用Stride4(也就是说,两个连续像素之间有一个字节的间隔)。哪种方法最好?(我也希望尽可能地优化,因为我必须多次这样做)。

假设输入数组是
(n,m,3)
,那么它可以通过简单地连接
(n,m,4)
数组扩展到
(n,m,4)

X = np.ones((n,m,3), dtype='byte')
F = np.zeros((n,m,1), dtype='byte')
X1 = np.concatenate([X,F], axis=2)
它们的跨步是
(3*m,3,1)
(m,1,1)
(4*m,4,1)

同样的数据也可以输入

In [72]: dt0 = np.dtype([('R','u1'), ('G','u1'), ('B','u1')])
In [73]: X=np.ones((n,m),dtype=dt0)
In [74]: X.strides
Out[74]: (150, 3)
In [75]: X.shape
Out[75]: (30, 50)
目标具有
dt=np.dtype([('R','u1'),('G','u1'),('B','u1'),('A','u1')]))

将RGB字段映射到RGBA 但是为了连接这些数据类型,我们需要对
(n,m,3)
形状进行一些转换。看起来重新分配
数据
属性就可以了

n, m = 2, 4
dt1 = np.dtype([('R','u1'), ('G','u1'), ('B','u1'), ('A','u1')])
dt0 = np.dtype([('R','u1'), ('G','u1'), ('B','u1')])
X = np.arange(n*m*3,dtype='u1').reshape(n,m,3)
print repr(X)
X0 = np.zeros((n,m), dtype=dt0)
X0.data = X.data
print repr(X0)
X0.strides # (12, 3)

X1 = np.zeros((n,m), dtype=dt1)
F = np.zeros((n,m,1), dtype='u1')
X01 = np.concatenate([X, F], axis=2)
X1.data = X01.data
print repr(X1)
X1.strides # (12, 4)
制作:

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)]], 
      dtype=[('R', 'u1'), ('G', 'u1'), ('B', 'u1')])
array([[(0, 1, 2, 0), (3, 4, 5, 0), (6, 7, 8, 0), (9, 10, 11, 0)],
       [(12, 13, 14, 0), (15, 16, 17, 0), (18, 19, 20, 0), (21, 22, 23, 0)]], 
      dtype=[('R', 'u1'), ('G', 'u1'), ('B', 'u1'), ('A', 'u1')])
使用重叠的数据类型 下面是一种使用重叠数据类型而不是串联的方法:

dt0 = np.dtype([('R','u1'), ('G','u1'), ('B','u1')])
dt1 = np.dtype([('R','u1'), ('G','u1'), ('B','u1'), ('A','u1')])
dtb = np.dtype({'names':['rgb','rgba'],
                'offsets':[0,0],
                'formats':[dt0, dt1]})
X0 = np.zeros((n,m), dtype=dt0)
X0.data = X.data
X1 = np.zeros((n,m), dtype=dtb)
X1['rgb'][:] = X0
print repr(X1['rgba'])
或者,如果没有单独的命名字节字段,则更简单:

dt0 = np.dtype(('u1',(3,)))
dt1 = np.dtype(('u1',(4,)))
dtb = np.dtype({'names':['rgb','rgba'],
                'offsets':[0,0],
                'formats':[dt0, dt1]})
X = np.arange(n*m*3,dtype='u1').reshape(n,m,3)
X1 = np.zeros((n,m), dtype=dtb)
X1['rgb'][:] = X
X1['rgba']
(n,m,4)
,跨步
(m*4,4,1)

X1['rgb']
(n,m,3)
,但步幅相同
(m*4,4,1)

当你大步前进时使用
这种形状上的差异,但步幅上的相似性,表明他使用了
作为跨步。创建空的目标数组,并使用
作为_-stripped
选择要从
X
接收值的元素子集:

X1 = np.zeros((n,m,4),dtype='u1')
np.lib.stride_tricks.as_strided(X1, shape=X.shape, strides=X1.strides)[:] = X
print X1

输入数组
(n,m,3)
的形状也是这样吗?以及输出
(n,m,4)
?如果是这样,将
np.zero((n,m,1))
数组串联起来怎么样?哦,是的,就是这样。事实上,这很琐碎,但我没有想到。对不起,吵闹了。如果你想把它写成一个答案,我可以接受。我已经添加了一个
解决方案