Julia 中的多维数组理解

jar*_*bus 4 arrays list-comprehension julia

我可以创建以下 (length(X),) 数组:

[F(x) for x in X]
Run Code Online (Sandbox Code Playgroud)

但是,如果 F(x) 返回一个数组,是否有任何方法可以使用理解来创建多维数组,其中每行是 F(x),并且数组的维数是(length(X),length(F(x))

PaS*_*STE 7

在 Julia 中有很多方法可以做到这一点!按照你的内涵使用,转的阵列输出一个简单的方法F(x)为2维数组将串联的结果,无论是与vcathcat或更一般的cat,使用reduce过的参数操作:

F(x) = [x, x*2, x*3]
X = collect(1:5)
reduce(vcat, [F(x)' for x in X])
# 5×3 Array{Int64,2}:
#  1   2   3
#  2   4   6
#  3   6   9
#  4   8  12
#  5  10  15
Run Code Online (Sandbox Code Playgroud)

因为您特别请求了一个length(X)bylength(F(x))数组,所以'必须在 的输出上使用伴随运算符以F(x)正确定位vcat. 您也可以hcat对结果执行相同的操作并转置结果:

reduce(hcat, [F(x) for x in X])'
# 5×3 LinearAlgebra.Adjoint{Int64,Array{Int64,2}}:
#  1   2   3
#  2   4   6
#  3   6   9
#  4   8  12
#  5  10  15
Run Code Online (Sandbox Code Playgroud)

reduce调用是必需的,因为vcathcat的串连在一起,所有的参数-如果你只是给他们[F(x) for x in X],他们会认为你逝去的阵列中的一个单一的阵列和简单地返回,因为没有什么来连接。

您还应该查看函数广播,该功能使 Julia 与许多其他语言区分开来。它可以帮助减少其他语言中依赖列表推导式的代码的冗长。只需在您的函数名称之后和参数之前添加一个句点,即可自动在参数的所有元素上广播该函数!

Y = collect(2:2:10)
reduce(hcat, F.(Y))'
# 5×3 LinearAlgebra.Adjoint{Int64,Array{Int64,2}}:
#   2   4   6
#   4   8  12
#   6  12  18
#   8  16  24
#  10  20  30
Run Code Online (Sandbox Code Playgroud)

进阶:函数组合

正如@CameronBiegnanek 指出的那样,Julia 支持使用运算符的函数组合?。将两个函数组合在一起,如(G ? F)(x)translates to G(F(x)),因此您可以adjoint使用您的函数组合操作,F如下所示:

reduce(vcat, (adjoint ? F).(X))
Run Code Online (Sandbox Code Playgroud)

但是这种操作(在数组的所有元素上映射一个函数,然后使用另一个函数减少所有这些输出)是一种常见的处理数据的方法,称为“map-reduce”操作。Julia 有一个内置mapreduce函数可以做到这一点!

mapreduce(adjoint ? F, vcat, X)
Run Code Online (Sandbox Code Playgroud)