如何在Julia中实现类似于花式索引的功能?

时间:2018-10-02 15:21:25

标签: indexing julia

我是Julia的新手。因此,如果这是一个愚蠢的问题,请原谅。

我有一个4 * 4的矩阵AA

julia> AA
4×4 Array{Int64,2}:
  1   2   3   4
  5   6   7   8
  9  10  11  12
 13  14  15  16

我有一个包含索引信息的数组pvpq

julia> pv
3-element Array{Int64,1}:
 1
 3
 4

julia> pq
3-element Array{Int64,1}:
 2
 1
 4

我希望为元素AA[1,2]AA[3,1]AA[4,4]分配零。

如果我运行AA[pv,pq] = 0,则输出为:

4×4 Array{Int64,2}:
 0  0   3  0
 5  6   7  8
 0  0  11  0
 0  0  15  0 

但是我需要这个作为输出

4×4 Array{Int64,2}:
  1   0   3   4
  5   6   7   8
  0  10  11  12
 13  14  15  0

我知道这在Python中称为花式索引。但是,我该如何在Julia中做到这一点?我不能运行带有检查行和列索引的变量的两个if语句。

谢谢

3 个答案:

答案 0 :(得分:7)

另一种选择是使用CartesianIndex:

julia> AA[CartesianIndex.(pv, pq)]
3-element Array{Int64,1}:
  2
  9
 16

julia> AA[CartesianIndex.(pv, pq)] .= 0
3-element view(::Array{Int64,2}, CartesianIndex{2}[CartesianIndex(1, 2), CartesianIndex(3, 1), CartesianIndex(4, 4)]) with eltype Int64:
 0
 0
 0

julia> AA
4×4 Array{Int64,2}:
  1   0   3   4
  5   6   7   8
  0  10  11  12
 13  14  15   0

请注意,您必须使用.=而不是=,否则在1.0中会出现一个神秘的no method matching setindex_shape_check(::Int64, ::Int64)错误。.在0.7中会给出一个很好的弃用警告,这就是我应该可能仍在使用。 ;-)

答案 1 :(得分:4)

一个选项是

julia> for el in zip(pv, pq)
           AA[el...] = 0
       end

julia> AA
4×4 Array{Int64,2}:
  1   0   3   4
  5   6   7   8
  0  10  11  12
 13  14  15   0

答案 2 :(得分:1)

添加我的2美分来完成

Julia支持像matlab这样的“列-主序”线性索引(尽管我注意到Julia 1.0已弃用了sub2indind2sub等价的matlab函数)。

因此,如果您可以“线性索引”形式表示(或已经拥有)坐标,则可以直接将其用于索引。

在实践中,在当前的朱利亚状态下,这与使用笛卡尔索引看起来并没有太大区别,但是在某些情况下,例如,最好使用笛卡尔索引。如果您知道您将重复使用这些索引以进行进一步的操作,或者用于可读性/从matlab代码中转移等。

例如

julia> A = copy( reshape( 10:10:160, (4,4) )' )
4×4 Array{Int64,2}:
  10   20   30   40
  50   60   70   80
  90  100  110  120
 130  140  150  160

julia> pv = [1,3,4];   pq = [2,1,4];

julia> A_linearIndices = LinearIndices(A)
4×4 LinearIndices{2,Tuple{Base.OneTo{Int64},Base.OneTo{Int64}}}:
 1  5   9  13
 2  6  10  14
 3  7  11  15
 4  8  12  16

julia> L = [ A_linearIndices[i...] for i in zip(pv, pq) ]
3-element Array{Int64,1}:
  5
  3
 16

julia> A[L]
3-element Array{Int64,1}:
  20
  90
 160

julia> A[L] .= 0; A
4×4 Array{Int64,2}:
  10    0   30   40
  50   60   70   80
   0  100  110  120
 130  140  150    0

话虽如此,如果您想保留一些东西供以后建立索引,则还可以通过相同的方法保存布尔矩阵以进行逻辑索引。


编辑:代码也被编辑为通过线性索引显示分配。请注意,我必须制作一个适当的数组,而不是保留为“ ReshapedArray”对象,因为如果您尝试直接对其进行索引,后者会抱怨。