代码之家  ›  专栏  ›  技术社区  ›  Jim Maas

Julia,@view阻止生成新数组

  •  0
  • Jim Maas  · 技术社区  · 4 年前

    我的老朋友把3d数组叫做Pop,我想删除列(d2),当所有d3的值在d1==1的末尾时,我有以下代码:

    Pop[end, :, 1] .!=1
    

    我想加 @view 在此之前,将把更改写回Pop,同时在内存中生成一个额外的副本。这段代码运行良好

    @view(Pop[ :, Pop[end, :, 1] .!=1, :])
    

    但它不会改变名为Pop的原始3d阵列。我可以

    Pop = @view(Pop[ :, Pop[end, :, 1] .!=1, :])
    

    但我相信这会在内存中创建另一个副本,而我正试图避免这样做。我错过了哪些简单的语法?谢谢。J

    0 回复  |  直到 4 年前
        1
  •  2
  •   Benoit Pasquier Ricoter    4 年前

    @view 不会修改原始数组的大小,它提供了一个“视图”(例如,在您的情况下省略了一些列)。我认为这没什么错

    Pop = view(Pop, :, Pop[end, :, 1] .≠ 1, :)
    

    从现在起 Pop 是一个视图,你的旧,满 流行音乐 ,但它的行为类似于数组,因此您可以修改其条目,例如,您可以执行以下操作

    julia> using Random # using a fixed seed for reproducibility
    
    julia> Random.seed!(0) ;
    
    julia> Pop = rand(1:5, (2,4,2)) # original Pop
    2×4×2 Array{Int64,3}:
    [:, :, 1] =
     4  3  5  5
     1  1  3  5
    
    [:, :, 2] =
     2  2  3  1
     2  5  1  1
    
    julia> Pop[end,:,1] .≠ 1 # columns to keep
    4-element BitArray{1}:
     0
     0
     1
     1
    
    julia> Pop = view(Pop, :, Pop[end, :, 1] .≠ 1, :) # make it a view
    2×2×2 view(::Array{Int64,3}, :, [3, 4], :) with eltype Int64:
    [:, :, 1] =
     5  5
     3  5
    
    [:, :, 2] =
     3  1
     1  1
    
    julia> Pop[end,:,1] .= 1 ; # use your new view to manipulate data
    
    julia> Pop # view of the modified Pop
    2×2×2 view(::Array{Int64,3}, :, [3, 4], :) with eltype Int64:
    [:, :, 1] =
     5  5
     1  1
    
    [:, :, 2] =
     3  1
     1  1
    
    julia> Pop.parent # original full Pop (now Pop.parent) has been modified
    2×4×2 Array{Int64,3}:
    [:, :, 1] =
     4  3  5  5
     1  1  1  1
    
    [:, :, 2] =
     2  2  3  1
     2  5  1  1
    
    推荐文章