热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

Usingtimingtests,IfoundthatitsmuchmoreperformanttogrowVector{Array{Float64}}objectsus

Using timing tests, I found that it's much more performant to grow Vector{Array{Float64}} objects using push! than it is to simply use an Array{Float64} object and either hcat or vcat. However, after the computation is completed, I need to change the resulting object to an Array{Float64} for further analysis. Is there a way that works regardless of the dimensions? For example, if I generate the Vector of Arrays via

使用计时测试,我发现使用push来增加Vector {Array {Float64}}对象的性能要高得多!而不是简单地使用Array {Float64}对象和hcat或vcat。但是,在计算完成后,我需要将结果对象更改为Array {Float64}以进行进一步分析。有没有一种方法可以工作,无论尺寸?例如,如果我通过生成矢量数组

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

I can do the conversion like this:

我可以像这样进行转换:

fill = Array{Int}(size(uFull)...,size(u)...)
for i in eachindex(uFull)
  fill[i,:,:] = uFull[i]
end

but notice this requires that I know the arrays are matrices (2-dimensional). If it's 3-dimensional, I would need another :, and so this doesn't work for arbitrary dimensions.

但请注意,这需要我知道数组是矩阵(二维)。如果它是三维的,我需要另一个:,所以这对任意尺寸都不起作用。

Note that I also need a form of the "inverse transform" (except first indexed by the last index of the full array) in arbitrary dimensions, and I currently have

请注意,我还需要一个“逆变换”的形式(除了第一个由完整数组的最后一个索引索引)在任意维度,我目前有

filla = Vector{Array{Int}}(size(fill)[end])
  for i in 1:size(fill)[end]
filla[i] = fill[:,:,i]' 
end

I assume the method for the first conversion will likely solve the second as well.

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

2 个解决方案

#1


9  

This is the sort of thing that Julia's custom array infrastructure excels at. I think the simplest solution here is to actually make a special array type that does this transformation for you:

这是Julia的定制阵列基础设施擅长的事情。我认为这里最简单的解决方案是实际制作一个特殊的数组类型,为您进行这种转换:

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

Now just wrap your vector in a StackedArray and it'll behave like an N+1 dimensional array. This could be expanded and made more featureful (it could similarly support setindex! or even push!ing arrays to concatenate natively), but I think that it's sufficient to solve your problem. By simply wrapping uFull in a StackedArray you get an object that acts like an Array{T, N+1}. Make a copy, and you get exactly a dense Array{T, N+1} without ever needing to write a for loop yourself.

现在只需将您的矢量包装在StackedArray中,它的行为就像一个N + 1维数组。这可以扩展并使其更具特色(它可以类似地支持setindex!甚至推送数组本地连接),但我认为它足以解决您的问题。通过简单地将uFull包装在StackedArray中,您将获得一个类似于Array {T,N + 1}的对象。制作一个副本,你就可以获得一个密集的数组{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
…

Finally, I'll just note that there's another solution here: you could introduce the custom array type sooner, and make a GrowableArray that internally stores its elements as a linear Vector{T}, but allows pushing entire columns or arrays directly.

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

#2


5  

Matt B.'s answer is great, because it "simulates" an array without actually having to create or store it. When you can use this solution, it's likely to be your best choice.

Matt B.的答案很棒,因为它“模拟”了一个数组,而不必实际创建或存储它。当您可以使用此解决方案时,它可能是您的最佳选择。

However, there might be circumstances where you need to create a concatenated array (e.g., if you're passing this to some C code which requires contiguous memory). In that case you can just call cat, which is generic (it can handle arbitrary dimensions).

但是,在某些情况下您可能需要创建一个连接数组(例如,如果您将其传递给某些需要连续内存的C代码)。在这种情况下,你可以只调用cat,它是通用的(它可以处理任意维度)。

For example:

u =  [1 2 3 4
      1 3 3 4
      1 5 6 3
      5 2 3 1]
uFull = Vector{typeof(u)}(0)
push!(uFull,u)
for i = 1:10000
  push!(uFull,u)
end
ucat = cat(ndims(eltype(uFull))+1, uFull)

I took the liberty of making one important change to your code: uFull = Vector{typeof(u)}(0) because it ensures that the objects stored in the Vector container have concrete type. Array{Int} is actually an abstract type, because you'd need to specify the dimensionality too (Array{Int,2}).

我冒昧地对你的代码做了一个重要的改动:uFull = Vector {typeof(u)}(0)因为它确保了Vector容器中存储的对象具有具体的类型。 Array {Int}实际上是一个抽象类型,因为您还需要指定维度(Array {Int,2})。


推荐阅读
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • Whatsthedifferencebetweento_aandto_ary?to_a和to_ary有什么区别? ... [详细]
  • 本文介绍了Codeforces Round #321 (Div. 2)比赛中的问题Kefa and Dishes,通过状压和spfa算法解决了这个问题。给定一个有向图,求在不超过m步的情况下,能获得的最大权值和。点不能重复走。文章详细介绍了问题的题意、解题思路和代码实现。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 本文介绍了三种方法来实现在Win7系统中显示桌面的快捷方式,包括使用任务栏快速启动栏、运行命令和自己创建快捷方式的方法。具体操作步骤详细说明,并提供了保存图标的路径,方便以后使用。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • Redis底层数据结构之压缩列表的介绍及实现原理
    本文介绍了Redis底层数据结构之压缩列表的概念、实现原理以及使用场景。压缩列表是Redis为了节约内存而开发的一种顺序数据结构,由特殊编码的连续内存块组成。文章详细解释了压缩列表的构成和各个属性的含义,以及如何通过指针来计算表尾节点的地址。压缩列表适用于列表键和哈希键中只包含少量小整数值和短字符串的情况。通过使用压缩列表,可以有效减少内存占用,提升Redis的性能。 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
author-avatar
书友8649571
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有