代码之家  ›  专栏  ›  技术社区  ›  Francis Smart

按实例列表展开每个向量列表-Julia

  •  0
  • Francis Smart  · 技术社区  · 7 年前

    我想用一个包含每个实例数量的向量来展开每个值的向量。我已经想出了下面的代码来完成这项工作,但似乎这是一个常见的用法,所以我可能遗漏了一些东西。

    valuelist = ["a","b","d","z"]
    numberofinstance = [3,5,1,11]
    
    valuevector = String[]
    for i in 1:length(numberofinstance) 
      append!(valuevector , repeat([valuelist[i]], numberofinstance[i])) 
    end
    
    1 回复  |  直到 7 年前
        1
  •  5
  •   carstenbauer    7 年前

    如果您对使用包(基本上是stdlib)很满意,那么将调用您正在寻找的函数 inverse_rle 在里面 StatsBase.jl :

    julia> using StatsBase
    
    julia> inverse_rle(valuelist, numberofinstance)
    20-element Array{String,1}:
     "a"
     "a"
     "a"
     "b"
     "b"
     "b"
     "b"
     "b"
     "d"
     "z"
     "z"
     "z"
     "z"
     "z"
     "z"
     "z"
     "z"
     "z"
     "z"
     "z"
    
    julia> @btime inverse_rle($valuelist, $numberofinstance);
      76.799 ns (1 allocation: 240 bytes)
    
    julia> @btime yoursolution($valuelist, $numberofinstance);
      693.329 ns (13 allocations: 1.55 KiB)
    

    repeat ^ (通电)像这样,

    vcat(collect.(.^(valuelist, numberofinstance))...)

    但我认为这相对来说比较难解析,也比

    julia> @btime yoursolution($valuelist, $numberofinstance);
      693.329 ns (13 allocations: 1.55 KiB)
    
    julia> @btime vcat(collect.(.^($valuelist, $numberofinstance))...)
      472.615 ns (9 allocations: 800 bytes)
    

    快得多 比您的解决方案快(与 implementation in StatsBase

    function multiply(vs, ns)
       r = Vector{String}(undef, sum(ns))
       c = 1
       @inbounds for i in axes(ns, 1)
           for k in 1:ns[i]
               r[c] = vs[i]
               c += 1
           end
       end
       r
    end
    

    基准:

    julia> @btime yoursolution($valuelist, $numberofinstance);
      693.329 ns (13 allocations: 1.55 KiB)
    
    julia> @btime multiply($valuelist, $numberofinstance);
      76.469 ns (1 allocation: 240 bytes)