6

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?

holistic
  • 2,975
  • 15
  • 37

3 Answers3

9

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.

ubpdqn
  • 60,617
  • 3
  • 59
  • 148
5

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}]
ciao
  • 25,774
  • 2
  • 58
  • 139
  • (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 :) – ubpdqn Jul 05 '15 at 07:22
1
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