6
$\begingroup$

I have a list with negative and positive numbers

list = {-1, -2, 1, 2}

and I want to replace all negative values with 0 and all positive values with 1 simultaneously. I only managed to replace one value at a time and don't know how to add a second condition. I did the following

list /. x_ /; x<0->1

I want something like:

 list /. x_ /; {x<0->0 && x>0->1}

but this does not work. So how to add a second condition?

$\endgroup$

3 Answers 3

9
$\begingroup$

There a number of approaches. The desired behaviour of zero has not been specified.

Examples:

UnitStep[list]
Boole[# > 0] & /@ list
list /. {x_?Negative -> 0, x_?Positive -> 1}
HeavisideTheta[list]
(Unitize@# + Sign@#)/2 &@list

UnitStep[0] yields 1

The Boole approach will also yield zero but could be modified as desired.

The replacement rules has not specified zero so will leave it unchanged.

HeavisideTheta[0] yields HeavisideTheta[0]

The Unitize,Sign will yield 0.

There are other approaches.

$\endgroup$
7
  • $\begingroup$ list/. {x_?Negative -> 0, x_?Positive -> 1} worked for me. I don't understand why list /. {x_<0 -> 0, x_>0 -> 1}, does not work, I did not know ?Negatvie and ?Positive before. $\endgroup$
    – holistic
    Commented Jul 4, 2015 at 10:04
  • 1
    $\begingroup$ You can use list /. {x_ /; x < 0 -> 0, x_ /; x > 0 -> 1}, see the documentation on Condition. $\endgroup$ Commented Jul 4, 2015 at 10:32
  • 1
    $\begingroup$ I believe UnitStep[0] results in 1. I like the solution Sign[list] rather than Boole[#.0] & /@ list. I prefer using built-in functions whenever they work. From a learning perspective the functional approaches are good. $\endgroup$ Commented Jul 4, 2015 at 15:35
  • $\begingroup$ @JackLaVigne yes you are correct...apologies I will correct;) $\endgroup$
    – ubpdqn
    Commented Jul 5, 2015 at 1:29
  • 2
    $\begingroup$ Boole[Thread[list > 0]] will work nicely. $\endgroup$ Commented Jul 5, 2015 at 2:40
5
$\begingroup$

These s/b considerably faster on large lists than solutions posted so far:

For integer lists:

UnitStep[Subtract[list, 1]]

For real lists:

 UnitStep[Subtract[Sign@list, 1]]

And I'd venture this will be quickest:

Clip[list, {0, 0}, {0, 1}]
$\endgroup$
1
  • $\begingroup$ (rasher) the first two are essentially correction to map 0 to 0 (noting the dealing with zero was not specified in OP)...Clip very nice :) $\endgroup$
    – ubpdqn
    Commented Jul 5, 2015 at 7:22
1
$\begingroup$
list = {-1, -2, 1, 2, 0} 
Floor[(1 + Sign[#])/2]&/@list

Note that 0 is replaced by 0.

If you prefer to replace 0 by 1, you must use:

Ceiling[(1 + Sign[#])/2]&/@list 
$\endgroup$

Your Answer

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

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