Issue
I have a Numpy 2D matrix of zeros, and a Numpy list of coordinates. What I would like to do, is modify the matrix thanks to the list of coordinates by passing it in a function.
Here is what I tried :
import numpy as np
def update(coords):
return np_arr[coords[0]][coords[1]]+1
size = 3
np_arr = np.zeros((size,size))
dt = np.dtype('int', 'int')
np_indices = np.array([(x,y) for y in range(size) for x in range(size)], dtype=dt)
np_arr = update(np_indices)
print(np_arr)
I expected the output to be a size*size
matrix:
[[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]]
But instead I get:
[[1. 1. 1.]
[1. 1. 1.]]
Why does the shape of the matrix is not the same?
I know that I could simply use:
np_arr = np.array([[update(x,y) for y in range(size)] for x in range(size)])
However, I would like to avoid using np.array every time.
Solution
In [484]: size = 3
...: np_arr = np.zeros((size,size))
...: dt = np.dtype('int', 'int')
...: np_indices = np.array([(x,y) for y in range(size) for x in range(size)], dtype=dt)
In [485]: np_arr
Out[485]:
array([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]])
Despite using the compound dt
, the np_indices
array is a 2d int
dtype array. Were you hoping to get an array of tuples?
In [486]: np_indices
Out[486]:
array([[0, 0],
[1, 0],
[2, 0],
[0, 1],
[1, 1],
[2, 1],
[0, 2],
[1, 2],
[2, 2]])
Anyways, the way to index np_arr
is to use the 2 columns, as in:
In [487]: np_arr[np_indices[:,0],np_indices[:,1]]
Out[487]: array([0., 0., 0., 0., 0., 0., 0., 0., 0.])
In [488]: np_arr[np_indices[:,0],np_indices[:,1]]+=1
In [489]: np_arr
Out[489]:
array([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])
You can't use np_arr[np_indices[:,0]][np_indices[:,1]
. That applies the 2 indexing operations sequentially. It works for scalar indices, np_arr[2,3], np_arr[2][3]
, but not when using arrays. And np_indices[0]
is the first row, not column.
In [490]: size = 3
...: np_arr = np.zeros((size,size))
...: dt = np.dtype([('x','int'), ('y','int')])
...: np_indices = np.array([(x,y) for y in range(size) for x in range(size)], dtype=dt)
In [491]: np_indices
Out[491]:
array([(0, 0), (1, 0), (2, 0), (0, 1), (1, 1), (2, 1), (0, 2), (1, 2),
(2, 2)], dtype=[('x', '<i4'), ('y', '<i4')])
With a different dt
, we get a 1d structured array
:
In [492]: np_indices['x']
Out[492]: array([0, 1, 2, 0, 1, 2, 0, 1, 2])
We still need to use the 2 array indexing:
In [493]: np_arr[np_indices['x'],np_indices['y']]
Out[493]: array([0., 0., 0., 0., 0., 0., 0., 0., 0.])
The structured array could be used in loop:
In [495]: [np_arr[x,y] for x,y in np_indices]
Out[495]: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
but generally we avoid that.
Answered By - hpaulj
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.