7
$\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$ 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$ 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$ 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$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.