【问题标题】:Julia, @view to prevent production of a new arrayJulia,@view 以防止生成新数组
【发布时间】:2021-01-28 16:27:48
【问题描述】:

我的老朋友 3d 数组叫 Pop,我想删除列 (d2),当 d1 结尾的值 == 1 时,跨越所有 d3,所以我有这个代码:

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

我认为在此之前添加 @view 会将更改写回 Pop,而不会在内存中产生额外的副本。此代码运行良好

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

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

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

但我相信这会在内存中创建另一个我试图避免的副本。我错过了什么简单的语法?谢谢。 J

【问题讨论】:

标签: arrays julia row-removal


【解决方案1】:

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

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

因为现在Pop 是旧的完整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

【讨论】:

    猜你喜欢
    • 2011-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-17
    • 2020-01-07
    • 1970-01-01
    • 2013-09-23
    • 1970-01-01
    相关资源
    最近更新 更多