arrays - Julia:将数组向量转换为任意维度的数组

标签 arrays type-conversion julia

使用时序测试,我发现增长 Vector{Array{Float64}} 的性能要高得多对象使用 push!而不是简单地使用 Array{Float64}对象和其中之一 hcatvcat .但是,计算完成后,我需要将结果对象更改为Array{Float64}作进一步分析。有没有一种不管尺寸如何都有效的方法?例如,如果我生成 VectorArray通过

u =  [1 2 3 4
      1 3 3 4
      1 5 6 3
      5 2 3 1]
uFull = Vector{Array{Int}}(0)
push!(uFull,u)
for i = 1:10000
  push!(uFull,u)
end

我可以像这样进行转换:
fill = Array{Int}(size(uFull)...,size(u)...)
for i in eachindex(uFull)
  fill[i,:,:] = uFull[i]
end

但请注意,这要求我知道数组是矩阵(二维)。如果它是 3 维的,我需要另一个 : ,因此这不适用于任意维度。

请注意,我还需要一种任意维度的“逆变换”形式(除了首先由完整数组的最后一个索引索引),我目前有
filla = Vector{Array{Int}}(size(fill)[end])
  for i in 1:size(fill)[end]
filla[i] = fill[:,:,i]' 
end

我假设第一个转换的方法也可能解决第二个。

最佳答案

这就是 Julia 的 custom array infrastructure擅长。我认为这里最简单的解决方案是实际制作一个特殊的数组类型来为您执行此转换:

immutable StackedArray{T,N,A} <: AbstractArray{T,N}
    data::A # A <: AbstractVector{<:AbstractArray{T,N-1}}
    dims::NTuple{N,Int}
end
function StackedArray(vec::AbstractVector)
    @assert all(size(vec[1]) == size(v) for v in vec)
    StackedArray(vec, (length(vec), size(vec[1])...))
end
StackedArray{T, N}(vec::AbstractVector{T}, dims::NTuple{N}) = StackedArray{eltype(T),N,typeof(vec)}(vec, dims)
Base.size(S::StackedArray) = S.dims
@inline function Base.getindex{T,N}(S::StackedArray{T,N}, I::Vararg{Int,N})
    @boundscheck checkbounds(S, I...)
    S.data[I[1]][Base.tail(I)...]
end

现在只需将您的向量包装在 StackedArray 中,它的行为就像一个 N+1 维数组。这可以扩展并使其功能更强大(它同样可以支持 setindex! 甚至 push! 数组以进行本地连接),但我认为这足以解决您的问题。通过简单地包装 uFullStackedArray你会得到一个行为类似于 Array{T, N+1} 的对象.做个 copy ,你会得到一个密集的 Array{T, N+1}无需自己编写 for 循环。
julia> S = StackedArray(uFull)
10001x4x4 StackedArray{Int64,3,Array{Array{Int64,2},1}}:
[:, :, 1] =
 1  1  1  5
 1  1  1  5
 1  1  1  5
…

julia> squeeze(S[1:1, :, :], 1) == u
true

julia> copy(S) # returns a dense Array{T,N}
10001x4x4 Array{Int64,3}:
[:, :, 1] =
 1  1  1  5
 1  1  1  5
…

最后,我会注意到这里还有另一个解决方案:你可以早点引入自定义数组类型,并制作一个 GrowableArray在内部将其元素存储为线性 Vector{T} ,但允许直接推送整个列或数组。

关于arrays - Julia:将数组向量转换为任意维度的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37476815/

相关文章:

java - 如何将 ArrayList 添加到 2D ArrayList 而不覆盖之前的条目?

javascript - 按属性对对象数组进行排序(使用自定义顺序,而不是按字母顺序)

arrays - 在 Julia 中将 CartesianIndex 数组转换为 2D 矩阵

c# - SqlParameter 数组到对象

java - 推送到定义的二维数组

pandas - 写入文件时,numpy 数组更改为字符串

Java bigdecimal 或 double

c++ - 将长度恰好为8的倍数的 '1'和 '0'字符串转换为一定字节数

unit-testing - 如何为未导出的函数编写单元测试?

python - 创建大量对象(神经元)并使用字典随机连接