5

I have a 3D NumPy array that I want to convert to a 3D sparse matrix in Python. I looked up scipy.sparse module and only found 2D sparse matrix implementations. For example,

Input:

array([[[0],
        [0],
        [1],
        [0],
        [1],
        [0],
        [0]],
       [[1],
        [0],
        [1],
        [0],
        [0],
        [0],
        [0]]])

Output:

(0,0,2) 1
(0,0,4) 1
(0,1,0) 1
(0,1,2) 1

How would do this?

K. K.
  • 552
  • 1
  • 11
  • 20
  • Possible duplicate of [How to transform numpy.matrix or array to scipy sparse matrix](https://stackoverflow.com/questions/7922487/how-to-transform-numpy-matrix-or-array-to-scipy-sparse-matrix) – Lucas Sep 06 '18 at 04:30
  • 2
    Hi Lucas, I tried it already. They expect a dimension of 2 or less than 2. In my case, the dimension of the array is 3. – K. K. Sep 06 '18 at 04:32
  • 3
    As you note the `scipy.sparse` code only works with 2d. What do you want to do with the sparse matrix once you have it? It's one thing to represent the values, it's quite another to do something meaningful with them. – hpaulj Sep 06 '18 at 05:24
  • 2
    Yeah, it's fairly simple to create a `dok` or `lil` implementation in 3d, but without the algorithms that let `csr` and `csc` implementations do matrix math, they won't be particularly useful. If the matrix is some sort of transfer function you would probably be better flattening the input and output and storing the transformation in 2D. This is how, for example, a 4D symmetric transform can be represented in 2D via [Voigt Notation](https://en.wikipedia.org/wiki/Voigt_notation) – Daniel F Sep 06 '18 at 06:13

1 Answers1

0

in n dimensions,you can find the indices with:

ind=np.array(np.where(a!=0)).T
#array([[0, 2, 0],
#       [0, 4, 0],
#       [1, 0, 0],
#       [1, 2, 0]], dtype=int64)

and the corresponding values for example with:

ravel_ind=np.apply_along_axis(ravel_multi_index,1,ind,a.shape)
values=np.take(a,ravel_ind)
# array([1, 1, 1, 1])  
B. M.
  • 18,243
  • 2
  • 35
  • 54