2

I've got a matrix of values, and I want a vector with the positions of the matrix and the value.

First idea: double-bucle and store index and value

Second idea: Create a ndarray whit a sequence

Any other idea most efficient?

Sorry for my english.

Input (image 1C):

[[0 1 2 3 4 5]
 [6 7 8 9 10 11]]

Output:

[[0 0 1][0 1 2] [0 2 3] [0 3 4] [0 4 5] [1 0 6] [1 1 7] [1 2 8] [1 3 9] [1 4 10] [1 5 11] ... ]

Thank you all for your answers, you have helped to solve the problem and understand numpy.

1
  • 2
    please include sample input+output so it's easier to understand what you're asking. Commented Nov 16, 2013 at 21:38

3 Answers 3

2

Here's a pretty clean way to do it:

import numpy as np
arr = np.random.random((2, 6))
x, y = np.indices(arr.shape)
output = np.column_stack([x.ravel(), y.ravel(), arr.ravel()])

And here's a overly cute way to do it that minimizes memory usage:

import numpy as np
arr = np.random.random((2, 6))
output = np.indices(arr.shape + (1,), dtype=arr.dtype)
output[-1, ..., 0] = arr
output = output.reshape(arr.ndim + 1, -1).T
Sign up to request clarification or add additional context in comments.

1 Comment

I test the indices, but for large arrays indices don't work well. Sorry, I don't say anything about the size of the matrix (and the example was poor). But your approach (stack columns) has been useful.
1

Use numpy.ndenumerate.

list(np.ndenumerate(a))
=>
[((0, 0), 0),
 ((0, 1), 1),
 ((0, 2), 2),
 ((0, 3), 3),
 ((0, 4), 4),
 ((0, 5), 5),
 ((1, 0), 6),
 ((1, 1), 7),
 ((1, 2), 8),
 ((1, 3), 9),
 ((1, 4), 10),
 ((1, 5), 11)]

To get the output you specified in the question, i.e. to flatten the indices and the values, you can do:

[ list(idx) + [value] for idx, value in np.ndenumerate(a) ]

Comments

1
import numpy as np

mat = np.arange(12).reshape(2,6)

result = np.c_[(np.array(list(np.ndindex(mat.shape))), mat.ravel())]
print(result)

yields

[[ 0  0  0]
 [ 0  1  1]
 [ 0  2  2]
 [ 0  3  3]
 [ 0  4  4]
 [ 0  5  5]
 [ 1  0  6]
 [ 1  1  7]
 [ 1  2  8]
 [ 1  3  9]
 [ 1  4 10]
 [ 1  5 11]]

Caution: Using list as in np.array(list(np.ndindex(mat.shape))) forms a temporary Python list. It's convenient, but not very memory-efficient since Python lists are much bigger than "equivalent" NumPy arrays. You could avoid the temporary Python list by using np.fromiter; for example, (in conjunction with shx2's ndenumerate idea):

import numpy as np
arr = np.arange(12).reshape(2,6)

def ndindex_values(arr):
    for idx, value in np.ndenumerate(arr):
        for coord in idx:
            yield coord
        yield value

result = np.fromiter(
    ndindex_values(arr),
    count=arr.size*(len(arr.shape)+1),
    dtype=arr.dtype).reshape(arr.size, -1)

2 Comments

just now i was reading about np.indices to create the array from this approach. Thanks!
I can't think of a good reason why you'd want to form this array. That might just be a lack of imagination on my part, but it might be because forming this array is typically not necessary. You might want to post a new question explaining your intended purpose for this array; people might be able to suggest a different approach which avoids it altogether.

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.