我想将 epsilon 以下的绝对值截断为 0,例如,
Truncate[{-3, -2, -1, 0, 1, 2, 3}, 1.5] -> {-3, -2, 0, 0, 0, 2, 3}
我想我可以使用 Scan[] 和 If[] 编写一个函数,但是在 Mathematica 中是否有更惯用的“单线”方法呢?
我想将 epsilon 以下的绝对值截断为 0,例如,
Truncate[{-3, -2, -1, 0, 1, 2, 3}, 1.5] -> {-3, -2, 0, 0, 0, 2, 3}
我想我可以使用 Scan[] 和 If[] 编写一个函数,但是在 Mathematica 中是否有更惯用的“单线”方法呢?
很多选项都有效:
Map[If[Abs[#] < 1.5, 0, #] &, {-3, -2, -1, 0, 1, 2, 3}]
或等价物:
If[Abs[#] < 1.5, 0, #] & /@ {-3, -2, -1, 0, 1, 2, 3}
或者,如果您愿意:
ReplaceAll[{-3, -2, -1, 0, 1, 2, 3}, (x_ /; Abs[x] < 1.5) -> 0]
这相当于:
{-3, -2, -1, 0, 1, 2, 3} /. (x_ /; Abs[x] < 1.5) -> 0
或者
ReplaceAll[{-3, -2, -1, 0, 1, 2, 3}, (x_?(Abs[#] < 1.5 &)) -> 0]
这相当于:
{-3, -2, -1, 0, 1, 2, 3} /. (x_?(Abs[#] < 1.5 &)) -> 0
内置函数Chop
几乎正是您正在寻找的(它确实适用于列表,如您的示例中所示)。一个潜在的惊喜是它不截断(截断)整数,只截断浮点数。因此,为了让您的示例按预期工作,首先使用以下函数将列表转换为浮点数N
:
Chop[N@{-3, -2, -1, 0, 1, 2, 3}, 1.5] -> {-3., -2., 0, 0, 0, 2., 3.}
正如 Ramashalanka 所示,为了更普遍地做这种事情,我建议:
If[Abs[#]<1.5&, 0, #]& /@ {-3, -2, -1, 0, 1, 2, 3}
即,映射到列表上的 lambda 函数。
f3
这是一个快近一个数量级的方法 ( )。
它改编自 Fred Simons 的代码。
f1 = If[Abs[#] < 1.5, 0, #] & /@ # &;
f2 = # /. (x_ /; Abs[x] < 1.5) -> 0 &;
f3 = # (1 - Unitize@Clip[#, {-1.5, 1.5}, {0, 0}]) &;
lst = RandomInteger[{-100, 100}, 5000];
SameQ @@ (#@lst & /@ {f1, f2, f3})
First@Timing@Do[#@lst, {500}] & /@ {f1, f2, f3}
(* Out= True *)
(* Out= {0.406, 2.282, 0.047} *)