采用以下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背景,这种行为对我来说非常奇怪。
答案 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
的返回值上调用reshape
或a[:,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,:]
。标量索引的所有维度现在都被删除了,一般来说,输出的维数是索引维度的总和。