 <p>Assuming the input array is <code>(n,m,3)</code>, then it can be expanded to <code>(n,m,4)</code> by simply concatenating a <code>(n,m,1)</code> array.</p> <pre><code>X = np.ones((n,m,3), dtype='byte') F = np.zeros((n,m,1), dtype='byte') X1 = np.concatenate([X,F], axis=2) </code></pre> <p>Strides for these are <code>(3*m,3,1)</code>, <code>(m,1,1)</code> and <code>(4*m,4,1)</code>.</p> <p>The same data could put in</p> <pre><code>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) </code></pre> <p>With the target having <code>dt = np.dtype([('R','u1'), ('G','u1'), ('B','u1'), ('A','u1')])</code> <a href="http://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html" rel="nofollow">http://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html</a></p> <h2>Mapping RGB fields to RGBA</h2> <p>But to do concatenation with these dtypes, we'd do some sort of casting to the <code>(n,m,3)</code> shape. Looks like reassigning the <code>data</code> attribute will do the trick.</p> <pre><code>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) </code></pre> <p>producing:</p> <pre><code>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')]) </code></pre> <h2>Using overlapping dtypes</h2> <p>Here's a way of doing it with overlapping dtypes rather than concatenation:</p> <pre><code>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']) </code></pre> <p>Or without the individual named byte fields it's even simpler:</p> <pre><code>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 </code></pre> <p><code>X1['rgba']</code> is <code>(n,m,4)</code>, with strides <code>(m*4, 4, 1)</code>.</p> <p><code>X1['rgb']</code> is <code>(n,m,3)</code>, but with the same strides <code>(m*4, 4, 1)</code>.</p> <h2>Using <code>as_strided</code></h2> <p>That difference in shape, but similarity in strides, suggest's using <code>as_strided</code>. Create the empty target array, and use <code>as_strided</code> to select a subset of elements to receive values from <code>X</code>:</p> <pre><code>X1 = np.zeros((n,m,4),dtype='u1') np.lib.stride_tricks.as_strided(X1, shape=X.shape, strides=X1.strides)[:] = X print X1 </code></pre>