点列表上的功能映射

Sir*_*sen 1 wolfram-mathematica

我有一个点列表:

points = {{0.144, 1.20}, {0.110, 1.60}, {0.083, 2.00}, {0.070, 2.40},
         {0.060, 2.80}, {0.053, 3.20}, {0.050, 3.60}, {0.043, 4.00}}
Run Code Online (Sandbox Code Playgroud)

我想将每个点传递给这个函数,返回一个新点:

coordinate[length_,frequence_] = {(1/(2*length)) , (frequence*1000)}
Run Code Online (Sandbox Code Playgroud)

这应该导致如下列表:

 { {3.47, 12 000}, {4.54, 16 000}, ... }
Run Code Online (Sandbox Code Playgroud)

我一直试图用地图这样做:

 data = Map[coordinate, points]
Run Code Online (Sandbox Code Playgroud)

它产生如下:

 {coordinate[{0.144, 1.2}], coordinate[{0.11, 1.6}]}
Run Code Online (Sandbox Code Playgroud)

起初看起来是正确的,除了它传递一个列表而不仅仅是参数.但是,即使我将我的coordinate函数更改为接受列表(通过将预期参数list_更改length为更改为list[[1]]frequence更改list[[2]]),我也无法使用该映射返回的列表进行线性回归LinearModelFit[data, x, x]["BestFit"].

Sim*_*mon 9

使用您的定义的最简单方法是Apply在1级,它具有速记@@@.(请参阅Apply文档的更多信息部分.)所以,你想要的

points = {{0.144, 1.20}, {0.110, 1.60}, {0.083, 2.00}, {0.070, 
   2.40}, {0.060, 2.80}, {0.053, 3.20}, {0.050, 3.60}, {0.043, 4.00}}

coordinate[length_, frequence_] := {(1/(2*length)), (frequence*1000)}

coordinate @@@ points
Run Code Online (Sandbox Code Playgroud)

请注意,我已将您的定义更改为a SetDelayed而不是仅仅Set(注意语法突出显示右侧显示的本地化变量).请参阅立即和延迟定义指南页面.

coordinate就是说,最好是制作一个列表而不是序列,就像在belisarius'和ninjagecko的答案中所做的那样,即,

coordinate[{length_, frequence_}] := {(1/(2*length)), (frequence*1000)}
Run Code Online (Sandbox Code Playgroud)

  • 就个人而言,我更喜欢`Apply [..,1]`方法 - 我认为它使得代码更易于读/写.(出于某种原因,我厌恶使用`Part`,除非我绝对必须......) (2认同)
  • @Brett我分享你对美学的感觉,但有时我会选择基于'Part`的表现因为性能考虑.对于大型列表,使用"Apply"通常会阻止自动编译.如果我们用模式定义`coordinate`并不重要,但是如果我们使用`coordinate = {#/ 2,#2*1000}和`的纯函数,那么无关紧要``Apply [...,1]`和`coordinatePart = {#[[1]]/2,#[[2]]*1000}&`for`Map`.使用像`pointsFreqs = RandomReal [{1,10},{100000,2}];`这样的测试样本,您可以观察到自动编译`Map`而不是`Apply`的显着性能优势. (2认同)