Simpler way to create a matrix/list of indices?

跟風遠走 提交于 2019-12-02 19:45:54

问题


I wonder what could be the easiest way to create a bi-dimensional array, that has for each row the indices to another multi-dimensional array.

For example, let's say I have a cube 4x4, the "indices matrix" would be the following:

np.concatenate([
    np.expand_dims(curr.ravel(),axis=0).T
    for curr
    in np.meshgrid(
        np.arange(4),
        np.arange(4),
        np.arange(4)
    )
],axis=1)

with the following result:

array([[0, 0, 0],
      [0, 0, 1],
      [0, 0, 2],
      [0, 0, 3],
      [1, 0, 0],
      [1, 0, 1],
      ...
      [2, 3, 2],
      [2, 3, 3],
      [3, 3, 0],
      [3, 3, 1],
      [3, 3, 2],
      [3, 3, 3]])

Besides the fact that it seems that the second column should be in place of the first, is there a more "numpythonic" way to create the same or similar matrix in a more compact way?

It would be nice if existed a function that just takes an arbitrary multi-dimensional array and returns it's index table.


回答1:


You could use np.indices:

>>> a = np.random.random((4,4,4))
>>> np.indices(a.shape).reshape((a.ndim, -1)).T
array([[0, 0, 0],
       [0, 0, 1],
       [0, 0, 2],
       [0, 0, 3],
       [0, 1, 0],
       [0, 1, 1],
[...]
       [3, 3, 2],
       [3, 3, 3]])

There are also other utilities like np.ndindex, depending on your use case. (FWIW I don't think getting the coordinates in the form you're looking for is going to be as helpful as you might think it is, but YMMV.)




回答2:


I think

list(itertools.product(range(4),range(4),range(4)))

is more pythonic. .. (note you could use numpy.array instead of list if you were so inclined...)




回答3:


It would be nice if existed a function that just takes an arbitrary multi-dimensional array and returns it's index table.

If I understand your question, there is: indices:

i = np.indices(a.shape)

This doesn't give you the results in the shape you wanted:

>>> a = np.array([[1,2], [3,4], [5,6]])
>>> print(np.indices(a.shape))
[[[0 0]
  [1 1]
  [2 2]]

 [[0 1]
  [0 1]
  [0 1]]]

… but you can flatten it and transpose it:

[[0 0]
 [0 1]
 [1 0]
 [1 1]
 [2 0]
 [2 1]]



回答4:


Here's how to do what I think you actually want to do. From your comment:

I need to test some probability values that are stored in a 3-dimensional array. If they pass some test condition, then I will add them to a list of coordinates that will be visualized in a 3d scatter plot.

Let's say, for the same of simplicity, that the test is something simple, like "is positive". So, we just transform the array into a boolean array of "element is positive" for each element, which is just arr > 0, and then use nonzero to get the true indices of that boolean array:

>>> arr = np.array([[-1, 1], [2, -2], [-3, -3]])
>>> print(arr > 0)
[[False  True]
 [ True False]
 [False False]]
>>> print(np.nonzero(arr > 0))
(array([0, 1]), array([1, 0]))

Can't get much simpler than that.



来源:https://stackoverflow.com/questions/25026136/simpler-way-to-create-a-matrix-list-of-indices

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!