python - numpy reshaping multdimensional array through arbitrary axis -
so question regarding use of reshape , how functions uses each axis on multidimensional scale.
suppose have following array contains matrices indexed first index. what want achieve instead index columns of each matrix first index. in order illustrate problem, consider following example given numpy array indexes matrices first index z.
x = np.arange(9).reshape((3, 3)) y = np.arange(9, 18).reshape((3, 3)) z = np.dstack((x, y)).t
where z looks like:
array([[[ 0, 3, 6], [ 1, 4, 7], [ 2, 5, 8]], [[ 9, 12, 15], [10, 13, 16], [11, 14, 17]]])
and shape (2, 3, 3)
. here, first index 2 images , 3 x 3 matrix.
the question more phrased then, how use reshape obtain following desired output:
array([[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 9, 10, 11], [12, 13, 14], [15, 16, 17]])
whose shape (6, 3)
. achieves dimension of array indexes columns of matrix x , y presented above. natural inclination use reshape directly on z in following way:
out = z.reshape(2 * 3, 3)
but output following indexes rows of matrices , not columns:
array([[ 0, 3, 6], [ 1, 4, 7], [ 2, 5, 8], [ 9, 12, 15], [10, 13, 16], [11, 14, 17]]
could reshape used obtain desired output above? or more general, can control how each axis used when use reshape function?
two things:
i know how solve problem. can go through each element of big matrix (z) transposed , apply reshape in way above. increases computation time little bit , not problematic. not generalize , not feel python. wondering if there standard enlightened way of doing this.
i not clear on how phrase question. if has suggestion on how better phrase problem ears.
every array has natural (1d flattened) order elements. when reshape array, as though flattened first (thus obtaining natural order), , reshaped:
in [54]: z.ravel() out[54]: array([ 0, 3, 6, 1, 4, 7, 2, 5, 8, 9, 12, 15, 10, 13, 16, 11, 14, 17]) in [55]: z.ravel().reshape(2*3, 3) out[55]: array([[ 0, 3, 6], [ 1, 4, 7], [ 2, 5, 8], [ 9, 12, 15], [10, 13, 16], [11, 14, 17]])
notice in "natural order", 0 , 1 far apart. reshape it, 0 , 1 not next each other along last axis, want in desired array:
desired = np.array([[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 9, 10, 11], [12, 13, 14], [15, 16, 17]])
this requires reordering, in case can done swapaxes
:
in [53]: z.swapaxes(1,2).reshape(2*3, 3) out[53]: array([[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 9, 10, 11], [12, 13, 14], [15, 16, 17]])
because swapaxes(1,2)
places values in desired order
in [56]: z.swapaxes(1,2).ravel() out[56]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]) in [57]: desired.ravel() out[57]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17])
note reshape
method has order
parameter can used control (c- or f-) order elements read array , placed in reshaped array. however, don't think helps in case.
another way think limits of reshape
reshapes followed ravel same:
in [71]: z.reshape(3,3,2).ravel() out[71]: array([ 0, 3, 6, 1, 4, 7, 2, 5, 8, 9, 12, 15, 10, 13, 16, 11, 14, 17]) in [72]: z.reshape(3,2,3).ravel() out[72]: array([ 0, 3, 6, 1, 4, 7, 2, 5, 8, 9, 12, 15, 10, 13, 16, 11, 14, 17]) in [73]: z.reshape(3*2,3).ravel() out[73]: array([ 0, 3, 6, 1, 4, 7, 2, 5, 8, 9, 12, 15, 10, 13, 16, 11, 14, 17]) in [74]: z.reshape(3*3,2).ravel() out[74]: array([ 0, 3, 6, 1, 4, 7, 2, 5, 8, 9, 12, 15, 10, 13, 16, 11, 14, 17])
so if ravel of desired array different, there no way obtain reshaping.
the same goes reshaping order='f'
, provided ravel order='f'
:
in [109]: z.reshape(2,3,3, order='f').ravel(order='f') out[109]: array([ 0, 9, 1, 10, 2, 11, 3, 12, 4, 13, 5, 14, 6, 15, 7, 16, 8, 17]) in [110]: z.reshape(2*3*3, order='f').ravel(order='f') out[110]: array([ 0, 9, 1, 10, 2, 11, 3, 12, 4, 13, 5, 14, 6, 15, 7, 16, 8, 17]) in [111]: z.reshape(2*3,3, order='f').ravel(order='f') out[111]: array([ 0, 9, 1, 10, 2, 11, 3, 12, 4, 13, 5, 14, 6, 15, 7, 16, 8, 17])
it possible obtain desired array using 2 reshapes:
in [83]: z.reshape(2, 3*3, order='f').reshape(2*3, 3) out[83]: array([[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 9, 10, 11], [12, 13, 14], [15, 16, 17]])
but stumbled upon serendipidously.
if i've totally misunderstood question , x
, y
givens (not z
) obtain desired array using row_stack
instead of dstack
:
in [88]: z = np.row_stack([x, y]) in [89]: z out[89]: array([[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 9, 10, 11], [12, 13, 14], [15, 16, 17]])
Comments
Post a Comment