I am interested in filtering a sparse matrix, where the values are between zero and one. I do it in the following manner.

s = SparseArray[RandomInteger[{1, 20}, {5, 2}] -> RandomReal[1, 5]]
fs = Select[s["NonzeroValues"], # > 0.5 &]; // AbsoluteTiming

But I little bit confused by the result, I didn't get a sparse matrix (in the documentation written in an unclear way when Select return not sparse matrix Select documentation). Also, I am interesting to improve a runtime

  • $\begingroup$ Neither do I get why you expect to get a sparse matrix from Select nor what your issues with the runtime are. What is the output that you actually want? $\endgroup$ – Henrik Schumacher Aug 27 '18 at 18:30
  • $\begingroup$ Maybe SparseArray[Subtract[1, UnitStep[Subtract[0.5, s]]]] is what you look for... $\endgroup$ – Henrik Schumacher Aug 27 '18 at 18:35
  • 1
    $\begingroup$ @HenrikSchumacher, please take a look to subsection "Generalizations & Extensions" in the Select documentation, you will find a two example. In my opinion, there are not consistent because in one case filtering of Sparse matrix give the Sparse matrix and in the second case filtering provides the list. $\endgroup$ – Kiril Danilchenko Aug 27 '18 at 18:41
  • 2
    $\begingroup$ Well, the first example uses EvenQ which embraces the background value (0) of the spare array. That's why the output is created as sparse vector with the same background value. In the second example, it is clear that the background value is ruled out so that there is some good reason to make the return value a dense, packed vector (a dense vector is the most appropriate data type for such data). But when you apply Select to s["NonzeroValues"], which is a dense array, then you will of course gain a dense array as return value. $\endgroup$ – Henrik Schumacher Aug 27 '18 at 18:46
  • 1
    $\begingroup$ @kglr I did not explain myself correctly, I mean transform and not delete $\endgroup$ – Kiril Danilchenko Aug 27 '18 at 19:16

Use Clip:

s = SparseArray[RandomInteger[{1, 20}, {5, 2}] -> RandomReal[1, 5]];
s2 = Clip[s, {0.5, 1}];

Through[{Min, Max, Mean, StandardDeviation}[Flatten@Normal@s]]    
(* {0, 0.994525, 0.00418259, 0.058275} *)

Through[{Min, Max, Mean, StandardDeviation}[Flatten@Normal@s2]]    
(* {0.5, 0.994525, 0.501648, 0.0285514} *)

The referenced documentation page does not explicitly state that Clip can be used on sparse arrays, but, well, SparseArray is one of the data structures Clip tries to handle efficiently.


You can use Clip also with .

Clip[s, {0.5, ∞}, {0., 0.}]

If you want to erase the the remove entries also from the sparsity pattern of the matrix, you have to wrap with SparseArray:

SparseArray[Clip[s, {0.5, ∞}, {0., 0.}]]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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