Reputation: 96264
Say I have a 2D array like the one below:
array([3, 6, 7
1,-1, 3])
I would like to get in 3 separate arrays the x
, y
and value
of the array . In other words:
x = [0, 1, 0, 1, 0, 1]
y = [0, 0, 1, 1, 2, 2]
values = [3, 1, 6, -1, 7, 3]
How can I do this?
For reference, this is what MATLAB calls linear indexing.
Upvotes: 4
Views: 3586
Reputation: 5933
You could do 2 loops (or nested list comprehension) with 2 enumerate(iterable) inside.
>>> import numpy as np
>>> ar1=np.ones([3,4])
>>> ar1
array([[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.]])
>>> ar1[::2,::3]=-1
>>> ar1[::3,:21]=-2
>>> ar1
array([[-2., -2., -2., -2.],
[ 1., 1., 1., 1.],
[-1., 1., 1., -1.]])
>>> x=[];y=[];values=[]
>>> for i,ari in enumerate(ar1):
... for j,valj in enumerate(ari):
... print i,j,valj
... x+=[i];y+=[j];values+=[valj]
...
0 0 -2.0
0 1 -2.0
0 2 -2.0
0 3 -2.0
1 0 1.0
1 1 1.0
1 2 1.0
1 3 1.0
2 0 -1.0
2 1 1.0
2 2 1.0
2 3 -1.0
Upvotes: 0
Reputation: 231335
If you have scipy
installed along with numpy
, you can use its sparse
module
from scipy import sparse
x = np.array([[3,6,7],[1,-1,3]])
M=sparse.coo_matrix(x.T)
M.data
# array([ 3, 1, 6, -1, 7, 3])
M.col
# array([0, 1, 0, 1, 0, 1])
M.row
# array([0, 0, 1, 1, 2, 2])
Looking at coo_matrix
I see that nonzero()
is used to get the indices:
row,col = x.T.nonzero()
data = x.T[row,col]
If there could be zeros in x
, you'd have use a work around like np.nonzero(np.ones(x.T.shape))
.
Upvotes: 3
Reputation: 25813
How about something like:
x, y = np.indices(array.shape)
x = x.ravel(order='F')
y = y.ravel(order='F')
values = array.ravel(order='F')
Upvotes: 5
Reputation: 74154
def xyval(A):
x, y = np.indices(A.shape)
return x.ravel(), y.ravel(), A.ravel()
Upvotes: 3
Reputation: 5019
Your values
array can be attained by using the flatten
method of a 2D array (matrix). Then it's just a matter of constructing the x
and y
arrays to contain the proper indices.
import numpy as np
import itertools
a = np.array([[3, 6, 7],
[1,-1, 3]])
idxs = np.array(list(itertools.product(*map(range, a.shape))))
x = idxs[:,0]
y = idxs[:,1]
values = a.flatten()
Testing this:
>>> x
array([0, 0, 0, 1, 1, 1])
>>> y
array([0, 1, 2, 0, 1, 2])
>>> values
array([ 3, 6, 7, 1, -1, 3])
>>> a[0,0]
3
>>> a[0,1]
6
>>> a[0,2]
7
>>> a[1,0]
1
>>> a[1,1]
-1
>>> a[1,2]
3
Upvotes: 1
Reputation: 86128
What about this:
import numpy as np
a = np.array([[3, 6, 7],
[1,-1, 3]])
n_rows, n_cols = a.shape
temp_x = np.repeat(np.arange(n_rows)[np.newaxis, :], n_cols, axis=0)
# construction of x can probably be simplified
x = temp_x.ravel()
y = np.repeat(np.arange(n_cols), n_rows)
values = a.ravel(order='F')
Result:
>>> x
array([0, 1, 0, 1, 0, 1])
>>> y
array([0, 0, 1, 1, 2, 2])
>>> values
array([ 3, 1, 6, -1, 7, 3])
Upvotes: 1