Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mathematica: Idiomatic way to replace values in a list that match a condition?

I want to truncate absolute values below an epsilon to 0, e.g.,

Truncate[{-3, -2, -1, 0, 1, 2, 3}, 1.5] -> {-3, -2, 0, 0, 0, 2, 3}

I guess I could write a function using Scan[] and If[], but is there a more idiomatic "one-liner" way of doing it in Mathematica?

like image 520
Larry OBrien Avatar asked Feb 11 '10 01:02

Larry OBrien


2 Answers

Lots of options that all work:

Map[If[Abs[#] < 1.5, 0, #] &, {-3, -2, -1, 0, 1, 2, 3}]

or the equivalent:

If[Abs[#] < 1.5, 0, #] & /@ {-3, -2, -1, 0, 1, 2, 3}

or, if you prefer:

ReplaceAll[{-3, -2, -1, 0, 1, 2, 3}, (x_ /; Abs[x] < 1.5) -> 0]

which is equivalent to:

{-3, -2, -1, 0, 1, 2, 3} /. (x_ /; Abs[x] < 1.5) -> 0

or

ReplaceAll[{-3, -2, -1, 0, 1, 2, 3}, (x_?(Abs[#] < 1.5 &)) -> 0]

which is equivalent to:

{-3, -2, -1, 0, 1, 2, 3} /. (x_?(Abs[#] < 1.5 &)) -> 0
like image 129
Ramashalanka Avatar answered Oct 08 '22 02:10

Ramashalanka


The built in function Chop is almost exactly what you're looking for (it does work on lists, as in your example). One potential surprise is that it doesn't chop (truncate) integers, only floating point numbers. So for your example to work as you might expect, first convert your list to floating point with the N function:

Chop[N@{-3, -2, -1, 0, 1, 2, 3}, 1.5] -> {-3., -2., 0, 0, 0, 2., 3.}

As Ramashalanka shows, to do this sort of thing more generally, I recommend:

If[Abs[#]<1.5&, 0, #]& /@ {-3, -2, -1, 0, 1, 2, 3}

Ie, a lambda function mapped over the list.

like image 32
dreeves Avatar answered Oct 08 '22 03:10

dreeves