在Mathematica中使用函数式编程计算列表元素之间的百分差异?

4

这源于一个相关的讨论,如何在Mathematica中使用函数式编程从列表中减去特定元素?

如何轻松计算列表中值之间的百分差?

链接问题使用Differences函数轻松计算列表中相邻元素的绝对差异。然而,无论内置的Differences函数在处理这个特殊问题时有多么容易,仍然存在如何执行不同操作的问题。

正如我之前提到的,我现在想要计算百分差。给定一个元素列表,{value1, value2, ..., valueN},如何对该列表执行像(value2-value1)/value1这样的操作?

我已经尝试找到一种方法来使用SlotSlotSequence来隔离特定元素,然后对它们应用自定义函数。如果有一种方法来隔离元素并对它们执行操作,那么这是最有效的方法吗?

3个回答

9
有几种自然的方法可以做到这一点。您可以使用Partition来形成“百分比减少”函数的参数列表:
In[3]:= list = {a, b, c, d, e};

In[4]:= Partition[list, 2, 1]

Out[4]= {{a, b}, {b, c}, {c, d}, {d, e}}

然后你可以应用一个函数到这些内容上:

In[6]:= f @@@ Partition[list, 2, 1]

Out[6]= {f[a, b], f[b, c], f[c, d], f[d, e]}

使用您的百分比减少函数:
In[7]:= PercentDecrease[a_, b_] := (b - a)/a

In[8]:= PercentDecrease @@@ Partition[list, 2, 1]

Out[8]= {(-a + b)/a, (-b + c)/b, (-c + d)/c, (-d + e)/d}

阅读应用页面上的“更多信息”注释,了解关于@@@的内容。

你可以使用MostRest代替Partition来形成第一和第二参数的列表,然后使用MapThread将它们组合起来:

In[14]:= MapThread[PercentDecrease, {Most[list], Rest[list]}]

Out[14]= {(-a + b)/a, (-b + c)/b, (-c + d)/c, (-d + e)/d}

另一种方法是将操作(减法和除法)分成两步,如下所示:
In[10]:= Differences[list] / Most[list]

Out[10]= {(-a + b)/a, (-b + c)/b, (-c + d)/c, (-d + e)/d}

除法运算符 (/) threads 作用于两个列表 Differences[list]Most[list]


很棒的答案!顺便说一下,我更喜欢这个对@@@的解释:https://dev59.com/k3M_5IYBdhLWcg3w-4hg#1141701 - dreeves
1
+1,非常好的答案。我个人最喜欢最后一个。虽然,我可能会写成Differences[#]/Most[#]& @ list,但这只是我的个人偏好。 - rcollyer

0
lst = {e, d, c, b, a};  (* ordered for display convenience *)
Ratios[lst] - 1   (* the answer *)
Together /@ %  (* just for display *)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接