Gio*_*ani 2 python arrays numpy
我有一个numpy数组,我想strides在修改数据的同时更改它,以便新数组描述数字的相同逻辑对齐.有没有办法做到这一点?
背景:我用一个图像文件读取cv2.imdecode(),产生一个BGR图像,其最低阶步幅设置为3(因此不同像素的通道之间没有间隙).我想用cairo包来修改这个图像,它想要使用步幅4(即两个连续像素之间的一个字节的间隙).哪种方法最好?(我也希望尽可能优化,因为我必须多次这样做).
假设输入数组是(n,m,3),则可以(n,m,4)通过简单地连接(n,m,1)数组来扩展它.
X = np.ones((n,m,3), dtype='byte')
F = np.zeros((n,m,1), dtype='byte')
X1 = np.concatenate([X,F], axis=2)
Run Code Online (Sandbox Code Playgroud)
这些的进步是(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)
Run Code Online (Sandbox Code Playgroud)
目标有dt = np.dtype([('R','u1'), ('G','u1'), ('B','u1'), ('A','u1')])
http://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html
但是为了与这些dtypes连接,我们会对(n,m,3)形状进行某种铸造.看起来重新分配data属性就可以了.
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)
Run Code Online (Sandbox Code Playgroud)
生产:
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')])
Run Code Online (Sandbox Code Playgroud)
这是一种使用重叠dtypes而不是连接来实现它的方法:
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'])
Run Code Online (Sandbox Code Playgroud)
或者没有单独命名的字节字段,它甚至更简单:
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
Run Code Online (Sandbox Code Playgroud)
X1['rgba']是(n,m,4),大踏步前进(m*4, 4, 1).
X1['rgb']是(n,m,3),但同样的步伐(m*4, 4, 1).
as_strided形状的差异,但大步相似,建议使用as_strided.创建空目标数组,并用于as_strided选择要从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
Run Code Online (Sandbox Code Playgroud)