5
$\begingroup$

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["AdjacencyLists"]
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.

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

1 Answer 1

6
$\begingroup$

You can Map over a SparseArray:

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

#["NonzeroValues"] & /@ sa
{{4}, {1}, {3, 2, 2}}
$\endgroup$
4
  • $\begingroup$ That is beautiful!!! did not know Map would work with SparseArray. For my large matrix had a timing of 0.000023. Thanks!!!!!!! $\endgroup$
    – ADDonut
    Jul 26, 2016 at 21:12
  • $\begingroup$ What exactly is being mapped in the expression for SparseArray? not really sure how it works. $\endgroup$
    – ADDonut
    Jul 26, 2016 at 21:15
  • $\begingroup$ @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}. $\endgroup$ Jul 26, 2016 at 21:32
  • $\begingroup$ @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) $\endgroup$
    – Mr.Wizard
    Jul 26, 2016 at 21:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.