4
$\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$
8
$\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$
  • $\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 Jul 4 '15 at 10:04
  • 1
    $\begingroup$ You can use list /. {x_ /; x < 0 -> 0, x_ /; x > 0 -> 1}, see the documentation on Condition. $\endgroup$ – Fred Simons Jul 4 '15 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$ – Jack LaVigne Jul 4 '15 at 15:35
  • $\begingroup$ @JackLaVigne yes you are correct...apologies I will correct;) $\endgroup$ – ubpdqn Jul 5 '15 at 1:29
  • 2
    $\begingroup$ Boole[Thread[list > 0]] will work nicely. $\endgroup$ – J. M. will be back soon Jul 5 '15 at 2:40
3
$\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$
  • $\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 Jul 5 '15 at 7:22
0
$\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, privacy policy and cookie policy

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