当使用映射的函数具有输入数组时使用映射

use*_*911 2 julia

Julia 的“高阶”函数“map”看起来非常有用。但是,虽然很容易理解如何在具有一个输入的函数上使用它,但当函数具有多个输入并且每个输入都可能是数组时,如何使用 map 并不明显。我想了解在这种情况下如何使用地图。

假设我有以下函数:

function randomSample(items, weights)
sample(items, Weights(weights))
end
Run Code Online (Sandbox Code Playgroud)

例子:

Pkg.add("StatsBase")
using StatsBase
randomSample([1,0],[0.5, 0.5])
Run Code Online (Sandbox Code Playgroud)

这里怎么用地图呢?我尝试过类似的事情:

items = [1 0;1 0;1 0]
weights = [1 0;0.5 0.5;0.75 0.25]

map(randomSample(items,weights))  
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,我希望 Julia 输出一个 3 x 1 的整数数组(来自项目),每行为 0 或 1,具体取决于相应的权重。

Bog*_*ski 5

在你的情况下,itemsweights可以Matrix使用eachrow这样的函数:

map(randomSample, eachrow(items), eachrow(weights))
Run Code Online (Sandbox Code Playgroud)

如果您使用的是 1.1 之前的 Julia 版本,您可以编写:

map(i -> randomSample(items[i, :], weights[i, :]), axes(items, 1))
Run Code Online (Sandbox Code Playgroud)

或者

map(i -> randomSample(view(items,i, :), view(weights, i, :)), axes(items, 1))
Run Code Online (Sandbox Code Playgroud)

(后者避免分配)

然而,实际上我可能会将items和定义weights为向量的向量:

items = [[1, 0],[1, 0],[1, 0]]
weights = [[1, 0], [0.5, 0.5], [0.75, 0.25]]
Run Code Online (Sandbox Code Playgroud)

然后你可以简单地写:

map(randomSample, items, weights)
Run Code Online (Sandbox Code Playgroud)

或者

randomSample.(items, weights)
Run Code Online (Sandbox Code Playgroud)

我的偏好的原因如下:

  • 从概念上更清楚数据的结构是什么
  • 向量的向量更容易变异(例如,您可以push!在末尾添加一个新条目)
  • 如果需要的话,向量的向量可以是不规则的
  • 在某些情况下,它可能会更快一些(在 Julia 中按行迭代并不是最佳选择,因为它使用列主索引;当然,您可以通过假设Matrix您按列存储数据而不是像当前那样按列存储数据来修复它)

(这不是一个非常强烈的偏好,你可以选择任何对你来说更方便的)

  • `eachrow` 需要 Julia 1.1。我将在答案中添加一条评论,告诉您如何在旧版本的 Julia 中执行操作。 (2认同)