1

Suppose I have the array:

[[2,1,5,2], 
 [1,4,2,1],
 [4,5,5,7],
 [1,5,9,3]]

I am trying to transpose the array to shape (16, 3) where the first two elements in the resulting array are the index numbers, and the last is the value. eg:

[[0, 0, 2], [1, 0, 1], [2, 0, 5], [3, 0, 2], [0, 1, 4], ....]

Is this possible with a numpy function or similar? Or I have to do this with my own function?

Working example code:

import numpy as np

src = np.array([[2,1,5,2],
                [1,4,2,1],
                [4,5,5,7],
                [1,5,9,3]])

dst = np.array([])


for x in range(src.shape[0]):
    for y in range(src.shape[1]):
        dst = np.append(dst, [[y, x, src[x][y]]])

print(dst.reshape(16,3))
1
  • Note on terminology: "transpose" on an array means to swap the rows and columns. This isn't what you are asking here. Commented Sep 19, 2019 at 16:48

2 Answers 2

1

I don't know if there is a function in numpy for that, but you can use list comprehension to easily build that array:

import numpy as np

src = np.array([[2,1,5,2],
                [1,4,2,1],
                [4,5,5,7],
                [1,5,9,3]])

dst = np.array([ [y, x, src[x][y]] 
                 for x in range(src.shape[0]) 
                 for y in range(src.shape[1])])

print(dst.reshape(16,3))

Hope this can help.

Sign up to request clarification or add additional context in comments.

Comments

0

Update: There is a numpy function for that:

You can use numpy.ndenumerate:

dst = np.array([[*reversed(x), y] for x, y in np.ndenumerate(src)])
print(dst)
#[[0 0 2]
# [1 0 1]
# [2 0 5]
# [3 0 2]
# [0 1 1]
# [1 1 4]
# [2 1 2]
# [3 1 1]
# [0 2 4]
# [1 2 5]
# [2 2 5]
# [3 2 7]
# [0 3 1]
# [1 3 5]
# [2 3 9]
# [3 3 3]]

ndenumerate will return an iterator yielding pairs of array coordinates and values. You will first need to reverse the coordinates for your desired output. Next unpack the coordinates into a list1 with the value and use a list comprehension to consume the iterator.


Original Answer

You can try:

dst = np.column_stack(zip(*[*reversed(np.indices(src.shape)), src])).T
print(dst)
#[[0 0 2]
# [1 0 1]
# [2 0 5]
# [3 0 2]
# [0 1 1]
# [1 1 4]
# [2 1 2]
# [3 1 1]
# [0 2 4]
# [1 2 5]
# [2 2 5]
# [3 2 7]
# [0 3 1]
# [1 3 5]
# [2 3 9]
# [3 3 3]]

Explanation

First, use numpy.indices to get an array representing the indices of a grid with the shape of src.

print(np.indices(src.shape))
#[[[0 0 0 0]
#  [1 1 1 1]
#  [2 2 2 2]
#  [3 3 3 3]]
#
# [[0 1 2 3]
#  [0 1 2 3]
#  [0 1 2 3]
#  [0 1 2 3]]]

We can reverse these (since that's the order you want in your final output), and unpack into a list1 that also contains src.

Then zip all of the elements of this list to get the (col, row, val) triples. We can stack these together using numpy.column_stack.

list(zip(*[*reversed(np.indices(src.shape)), src]))
#[(array([0, 1, 2, 3]), array([0, 0, 0, 0]), array([2, 1, 5, 2])),
# (array([0, 1, 2, 3]), array([1, 1, 1, 1]), array([1, 4, 2, 1])),
# (array([0, 1, 2, 3]), array([2, 2, 2, 2]), array([4, 5, 5, 7])),
# (array([0, 1, 2, 3]), array([3, 3, 3, 3]), array([1, 5, 9, 3]))]

Finally transpose (numpy.ndarray.T) to get the final output.

Notes:

  1. Unpacking into a list is only available in python 3.5+

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.