Arrays Julia中的多维数组理解
我可以创建以下(长度(X),)数组:Arrays Julia中的多维数组理解,arrays,julia,list-comprehension,Arrays,Julia,List Comprehension,我可以创建以下(长度(X),)数组: 但是,如果F(x)返回一个数组,是否有任何方法可以使用理解创建多维数组,其中每行是F(x),数组的维度是(长度(x),长度(F(x))?在Julia中有许多方法可以做到这一点!在使用理解之后,有一种简单的方法可以打开F(x)的数组输出将结果连接到一个二维数组中,可以使用或更通用的方法,并对参数进行操作: F(x) = [x, x*2, x*3] X = collect(1:5) reduce(vcat, [F(x)' for x in X]) # 5×3 A
但是,如果F(x)返回一个数组,是否有任何方法可以使用理解创建多维数组,其中每行是F(x),数组的维度是
(长度(x),长度(F(x))
?在Julia中有许多方法可以做到这一点!在使用理解之后,有一种简单的方法可以打开F(x)的数组输出
将结果连接到一个二维数组中,可以使用或更通用的方法,并对参数进行操作:
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
由于您通过length(F(X))
数组专门请求了length(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
reduce
调用是必需的,因为vcat
和hcat
将它们的所有参数连接在一起——如果您只给它们[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
高级:功能组合
正如@CameronBiegnanek指出的,Julia支持使用∘代码>运算符。将两个函数组合在一起,如(G∘ F) (x)
转换为G(F(x))
,因此您可以使用函数F
组合伴随操作,如下所示:
reduce(vcat, (adjoint ∘ F).(X))
reinterpret(reshape, T, [F(x) for x in X])
但是这种操作(将一个函数映射到一个数组的所有元素上,然后使用另一个函数减少所有这些输出)是处理数据的一种常见方法,称为“映射减少”操作。Julia有一个内置函数来完成这一操作
mapreduce(adjoint ∘ F, vcat, X)
如果F(x)
返回一个元组或a,那么即将发布的Julia 1.6将允许您按如下方式执行所需操作:
reduce(vcat, (adjoint ∘ F).(X))
reinterpret(reshape, T, [F(x) for x in X])
演示:
我不认为有一种方法可以通过数组理解直接做到这一点,但是有多种方法可以将向量向量转换成矩阵(其中一些在这里的堆栈溢出中进行了描述)。一般来说,建议使用reduce(vcat,a)
而不是像vcat(a…)
,因为散播大量参数不是很有效。Base Julia为reduce(vcat,a)
和reduce(hcat,a)
提供了优化方法。并且reduce和映射可以组合到一个调用中:mapreduce(伴随)∘ F、 vcat,X)
。很好,@CameronBieganek!我用reduce
更新了答案,并将添加奇特的函数组合。您可以使用生成器,而不是使用数组理解。理解将在连接之前分配一个临时数组,但生成器不会。例如尝试reduce(hcat,F(X)对于x中的x)
,不带方括号。