Matrix to Vector with python/numpy
<p>Numpy <code>ravel</code> works well if I need to create a vector by reading by rows or by columns. However, I would like to transform a matrix to a 1d array, by using a method that is often used in image processing. This is an example with initial matrix <code>A</code> and final result <code>B</code>:</p>

<pre><code>A = np.array([[ 0,  1,  2,  3],
              [ 4,  5,  6,  7],
              [ 8,  9, 10, 11],
              [12, 13, 14, 15]])

B = np.array([[ 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15])
</code></pre>

<p>Is there an existing function already that could help me with that? If not, can you give me some hints on how to solve this problem? PS. the matrix <code>A</code> is <code>NxN</code>.</p>

<p>I've been using numpy for several years, and I've never seen such a function.</p>

<p>Here's one way you could do it (not necessarily the most efficient):</p>

<pre><code>In [47]: a
Out[47]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])

In [48]: np.concatenate([np.diagonal(a[::-1,:], k)[::(2*(k % 2)-1)] for k in range(1-a.shape[0], a.shape[0])])
Out[48]: array([ 0,  1,  4,  8,  5,  2,  3,  6,  9, 12, 13, 10,  7, 11, 14, 15])
</code></pre>

<p>Breaking down the one-liner into separate steps:</p>

<p><code>a[::-1, :]</code> reverses the rows:</p>

<pre><code>In [59]: a[::-1, :]
Out[59]: 
array([[12, 13, 14, 15],
       [ 8,  9, 10, 11],
       [ 4,  5,  6,  7],
       [ 0,  1,  2,  3]])
</code></pre>

<p>(This could also be written <code>a[::-1]</code> or <code>np.flipud(a)</code>.)</p>

<p><code>np.diagonal(a, k)</code> extracts the <code>k</code>th diagonal, where <code>k=0</code> is the main diagonal.  So, for example,</p>

<pre><code>In [65]: np.diagonal(a[::-1, :], -3)
Out[65]: array([0])

In [66]: np.diagonal(a[::-1, :], -2)
Out[66]: array([4, 1])

In [67]: np.diagonal(a[::-1, :], 0)
Out[67]: array([12,  9,  6,  3])

In [68]: np.diagonal(a[::-1, :], 2)
Out[68]: array([14, 11])
</code></pre>

<p>In the list comprehension, <code>k</code> gives the diagonal to be extracted.  We want to reverse the elements in every other diagonal.  The expression <code>2*(k % 2) - 1</code> gives the values 1, -1, 1, ... as <code>k</code> varies from -3 to 3.  Indexing with <code>[::1]</code> leaves the order of the array being indexed unchanged, and indexing with <code>[::-1]</code> reverses the order of the array.  So <code>np.diagonal(a[::-1, :], k)[::(2*(k % 2)-1)]</code> gives the <code>k</code>th diagonal, but with every other diagonal reversed:</p>

<pre><code>In [71]: [np.diagonal(a[::-1,:], k)[::(2*(k % 2)-1)] for k in range(1-a.shape[0], a.shape[0])]
Out[71]: 
[array([0]),
 array([1, 4]),
 array([8, 5, 2]),
 array([ 3,  6,  9, 12]),
 array([13, 10,  7]),
 array([11, 14]),
 array([15])]
</code></pre>

<p><code>np.concatenate()</code> puts them all into a single array:</p>

<pre><code>In [72]: np.concatenate([np.diagonal(a[::-1,:], k)[::(2*(k % 2)-1)] for k in range(1-a.shape[0], a.shape[0])])
Out[72]: array([ 0,  1,  4,  8,  5,  2,  3,  6,  9, 12, 13, 10,  7, 11, 14, 15])
</code></pre>

python numpy