# How does AdjacencyLists work on SparseArray

I have been working with large SparseArray and have noticed the properties are very very useful and fast. I wanted to manipulate my large sparse array in ways similar to the properties. Looking at the full form seemed to give some clues.

If I have a sparse array

sa = SparseArray[{{0, 0, 0, 4}, {1, 0, 0, 0}, {3, 0, 2, 2}}]


then the internal sparse array structure is

sa // InputForm

SparseArray[Automatic, {3, 4}, 0, {1, {{0, 1, 2, 5}, {{4}, {1}, {1}, {3}, {4}}},
{4, 1, 3, 2, 2}}]


Look at some of the sparse array properties

sa["NonzeroValues"]
sa["NonzeroPositions"]


{4, 1, 3, 2, 2}

{{4}, {1}, {1, 3, 4}}

{{1, 4}, {2, 1}, {3, 1}, {3, 3}, {3, 4}}

So "NonzeroVaules" is apart of the internal structure. For "AdjacencyLists" we have the values which are the column indices in the internal structure. Then just have to group them. My guess would be to use the cumulative row indices in the internal structure {0, 1, 2, 5} something like 1-0=1 so group 1 element, then 2-1=1 partition 1 element (next element), 5-2=3 group next 3 elements. Giving the {{4}, {1}, {1, 3, 4}} But not sure how to do this.

"NonzeroPosition" done with same internal structures just appended cumulative row indices to column indices.

I would then like to take a large sparse matrix and take out the background values in this case 0 but leave the structure of instead of flattening it like "NonzeroValues". So I would get

{{4}, {1}, {3, 2, 2}}

I know this is easily done if converted to a dense matrix but want to keep it sparse since most of the values are zero and dealing with large matrix.

• Try GatherBy[Most[ArrayRules[SparseArray[{{0, 0, 0, 4}, {1, 0, 0, 0}, {3, 0, 2, 2}}]]], #[[1, 1]] &][[All, All, -1]]. Commented Jul 26, 2016 at 18:43

You can Map over a SparseArray:
sa = SparseArray[{{0, 0, 0, 4}, {1, 0, 0, 0}, {3, 0, 2, 2}}];

{{4}, {1}, {3, 2, 2}}

• That is beautiful!!! did not know Map would work with SparseArray. For my large matrix had a timing of 0.000023. Thanks!!!!!!! Commented Jul 26, 2016 at 21:12
• @MTR, it's entirely equivalent to #["NonzeroValues"] & /@ {SparseArray[{0, 0, 0, 4}], SparseArray[{1, 0, 0, 0}], SparseArray[{3, 0, 2, 2}]}, where e.g. SparseArray[{0, 0, 0, 4}]["NonzeroValues"] yields {4}. Commented Jul 26, 2016 at 21:32
• @MTR As J. M. commented the sparse array is effectively split into smaller sparse arrays. This is part of the "overloading" of SparseArray whereby it emulates a plain List array. You could also pull the rows with Part, e.g. Table[sa[[i]]["NonzeroValues"], {i, 3}] because that is overloaded in the same way, and it works for columns too, e.g. Table[sa[[All, i]]["NonzeroValues"], {i, 4}]. Note however that in a SparseArray rows and columns are not entirely interchangeable, e.g. please see: (25643) Commented Jul 26, 2016 at 21:44