Julia:跨不同结构实例的字段应用函数
Julia: applying function across fields of different struct instances
假设我有一个数组 my_array
,其元素是 myType
的实例,因此数组类型由 Array{myType,1}
.
给出
现在假设 my_array
中 myType
的每个实例都有一些字段 x
存储数据向量(例如 typeof(instance_of_myType.x) == Array{Float32,1}
)。
如果我知道数组中 myType
结构的每个实例的不同字段 x
具有相同的大小,有没有一种方法可以广播一个函数(例如平均或求和)跨越数组中所有 myType
实例的不同字段 x
,这将给我一个 Array{Float32,1}
向量,这是将函数应用于所有 [=15] 的结果=] my_array
中结构的字段?有没有没有 for 循环的方法,基本上就是我要问的?
这应该有效(除非您已为您的类型覆盖 getproperty
):
sum.(getproperty.(my_array, :x))
这是比较广播和使用理解的完整示例:
julia> struct A{T}
x::T
end
julia> my_array = [A(collect(i:i+3)) for i in 1:3]
3-element Array{A{Array{Int64,1}},1}:
A{Array{Int64,1}}([1, 2, 3, 4])
A{Array{Int64,1}}([2, 3, 4, 5])
A{Array{Int64,1}}([3, 4, 5, 6])
julia> sum.(getproperty.(my_array, :x))
3-element Array{Int64,1}:
10
14
18
julia> [sum(v.x) for v in my_array]
3-element Array{Int64,1}:
10
14
18
现在一个有趣的案例是,如果你想应用一个函数,例如sum
跨结构中字段 x
的各个元素。你可以得到这样的结果:
julia> sum(getproperty.(my_array, :x))
4-element Array{Int64,1}:
6
9
12
15
(注意这里唯一的区别是sum
后面没有.
)
或者像这样
julia> sum(v -> v.x, my_array)
4-element Array{Int64,1}:
6
9
12
15
编辑
所以一般的方法是:
julia> tmp = getproperty.(my_array, :x)
3-element Array{Array{Int64,1},1}:
[1, 2, 3, 4]
[2, 3, 4, 5]
[3, 4, 5, 6]
现在你可以写:
[fun(getindex.(tmp, i)) for i in eachindex(tmp...)]
假设fun
接受一个向量作为参数。
如果您想使用优秀的 SplitApplyCombine.jl 软件包,您可以这样写:
fun.(invert(getproperty.(my_array, :x)))
as invert
函数完全满足您的需求,例如:
julia> invert([[1,2,3], [4,5,6]])
3-element Array{Array{Int64,1},1}:
[1, 4]
[2, 5]
[3, 6]
假设我有一个数组 my_array
,其元素是 myType
的实例,因此数组类型由 Array{myType,1}
.
现在假设 my_array
中 myType
的每个实例都有一些字段 x
存储数据向量(例如 typeof(instance_of_myType.x) == Array{Float32,1}
)。
如果我知道数组中 myType
结构的每个实例的不同字段 x
具有相同的大小,有没有一种方法可以广播一个函数(例如平均或求和)跨越数组中所有 myType
实例的不同字段 x
,这将给我一个 Array{Float32,1}
向量,这是将函数应用于所有 [=15] 的结果=] my_array
中结构的字段?有没有没有 for 循环的方法,基本上就是我要问的?
这应该有效(除非您已为您的类型覆盖 getproperty
):
sum.(getproperty.(my_array, :x))
这是比较广播和使用理解的完整示例:
julia> struct A{T}
x::T
end
julia> my_array = [A(collect(i:i+3)) for i in 1:3]
3-element Array{A{Array{Int64,1}},1}:
A{Array{Int64,1}}([1, 2, 3, 4])
A{Array{Int64,1}}([2, 3, 4, 5])
A{Array{Int64,1}}([3, 4, 5, 6])
julia> sum.(getproperty.(my_array, :x))
3-element Array{Int64,1}:
10
14
18
julia> [sum(v.x) for v in my_array]
3-element Array{Int64,1}:
10
14
18
现在一个有趣的案例是,如果你想应用一个函数,例如sum
跨结构中字段 x
的各个元素。你可以得到这样的结果:
julia> sum(getproperty.(my_array, :x))
4-element Array{Int64,1}:
6
9
12
15
(注意这里唯一的区别是sum
后面没有.
)
或者像这样
julia> sum(v -> v.x, my_array)
4-element Array{Int64,1}:
6
9
12
15
编辑
所以一般的方法是:
julia> tmp = getproperty.(my_array, :x)
3-element Array{Array{Int64,1},1}:
[1, 2, 3, 4]
[2, 3, 4, 5]
[3, 4, 5, 6]
现在你可以写:
[fun(getindex.(tmp, i)) for i in eachindex(tmp...)]
假设fun
接受一个向量作为参数。
如果您想使用优秀的 SplitApplyCombine.jl 软件包,您可以这样写:
fun.(invert(getproperty.(my_array, :x)))
as invert
函数完全满足您的需求,例如:
julia> invert([[1,2,3], [4,5,6]])
3-element Array{Array{Int64,1},1}:
[1, 4]
[2, 5]
[3, 6]