切割不对称的多维Julia数组

时间:2014-01-16 03:34:44

标签: julia

采用以下2x2x2 Julia阵列:

julia> a
2x2x2 Array{Int32,3}:
[:, :, 1] =
 1  3
 2  4

[:, :, 2] =
 2  4
 3  5

我很惊讶地注意到沿不同维度切片会产生非对称结果:

julia> a[:,:,1]
2x2 Array{Int32,2}:
 1  3
 2  4

VS

julia> a[:,1,:]
2x1x2 Array{Int32,3}:
[:, :, 1] =
 1
 2

[:, :, 2] =
 2
 3

有人可以解释这里发生了什么吗?我来自numpy / MATLAB背景,这种行为对我来说非常奇怪。

3 个答案:

答案 0 :(得分:4)

如果你来自Matlab背景,这不应该太令人惊讶,因为Matlab以同样的方式工作:

>> a = reshape(1:8, 2, 2, 2)

a(:,:,1) =

     1     3
     2     4


a(:,:,2) =

     5     7
     6     8

>> b = a(:,:,1)

b =

     1     3
     2     4

>> ndims(b)

ans =

     2

>> c = a(:,1,:)

c(:,:,1) =

     1
     2


c(:,:,2) =

     5
     6

>> ndims(c)

ans =

     3

在Julia和Matlab中,在索引时添加额外的1并不是错误;即使b[2,2,1]是一个二维对象,你仍然可以写b

最后,如果你想要的东西更像numpy,请考虑(在Julia中)使用slice

julia> c = slice(a, :, 1, :)
2x2 SubArray{Int64,2,Array{Int64,3},(Range1{Int64},Int64,Range1{Int64})}:
 1  5
 2  6

julia> c = slice(a, :, 1:1, :)
2x1x2 SubArray{Int64,3,Array{Int64,3},(Range1{Int64},Range1{Int64},Range1{Int64})}:
[:, :, 1] =
 1
 2

[:, :, 2] =
 5
 6

你会得到一个SubArray返回(一个数组视图),它有一些稍微不同的属性,但从长远来看,很可能会被大多数索引操作返回。或者,如果您更喜欢数组,则可以在squeeze的返回值上调用reshapea[:,1,:]来获得所需的结果。

答案 1 :(得分:2)

目前,Julia在切片时会丢弃拖尾的单个尺寸,并且它可以在任何尺寸上保持一致。我认为这只是在切割矩阵行虎钳时我想要行向量(1 * n)而不是常规向量(n)的概括。

julia> a = [1 2; 3 4]
2x2 Array{Int64,2}:
 1  2
 3  4

julia> a[:,1]
2-element Array{Int64,1}:
 1
 3

julia> a[1,:]
1x2 Array{Int64,2}:
 1  2 

与matlab(和部分numpy)不同,Julia具有标量值和1d向量,因此不仅仅是一般的nd矩阵类型。我不认为你是第一个被这个属性搞糊涂的人。我记得看到删除所有单一维度的建议,并要求你a[1:1,:]来获取行向量,但我不确定会有更好的。

答案 2 :(得分:2)

现在,Julia 0.5已经改变了。现在切片是对称的"和a[:,:,1] == a[:,1,:]。标量索引的所有维度现在都被删除了,一般来说,输出的维数是索引维度的总和。