2016-07-26 216 views
2

我正在尝试使用向量来减少多维矩阵。Julia-通过向量提取多维矩阵的一部分

假设矩阵A是1000 x 10 x 100. 向量b可以是100 x 1,其中100个条目是A的第一维的一部分。第一个切片中总是只有一个元素A的尺寸与b的每个元素相匹配。

我该如何将矩阵简化为匹配向量?

我试图

Ared= A[b,:,:] 

,但它不工作。

这个例子中的新矩阵的形式应该为100×10×100

有没有人有什么想法?

+0

有在A的第一尺寸是b中的每个元素匹配一个元件总是。我不完全理解你的第二个问题。一般来说,我想创建一个与原始形状相同的新矩阵,但是第一个维度减少到向量b。 – Hainmueck

+0

你的问题含糊不清,并且吸引了两个相互矛盾但可能有效的答案,具体取决于你实际需要什么;你能指定你想要的吗?例如,如果“A”是“A =整形(0.1:0.1:2.4,3,4,2)”并且b是一个2元素向量,那么可以给出一个“b”和预期输出的例子吗? 'b'是你想用来选择'A'的子范围的行索引的向量吗? (例如'b = [1; 3]'),或者你说“b可以从'A(1,:,:)'(例如'b = [0.4; 1.9]')中可用的值中取两个值) ?请澄清 –

+0

如果是前者,请使用我的回答,如果是后者,请使用Michael的回答,如果不是,请用适当的例子重新说明并澄清您的问题。 –

回答

0

好吧,我想我明白你在问什么了。您正在寻找findin()功能。它有两个参数,每个参数都是一个集合。它查找第一个集合中的元素,并返回这些元素的索引。因此,我们可以将此函数应用于数组的第一维中的切片。下面是一些例子,从2D开始,为了简单起见,然后推广到3D,它们基本上是相同的。

请注意,有必要沿着第二和第三维选择特定的索引(这里我为每个选择了1),否则,第一维片中没有明确的元素与b的内容进行比较。 (每个维度简单地提供一部分,在这种情况下,一组3个数字,其中一起识别3D阵列内的特定地点)。

b = rand(100); 
using Distributions 
indices = sample(1:1000, 100, replace=false) ## random indices for where the elements in a slice of the first dimension of A will match those in b. 

## 2D example 
A = rand(1000,100); 
A[indices,1] = b; ## set 100 random rows of A will now have their first element match one element of b 
Ared = A[findin(A[:,1], b),:] ## find the rows in A where the first element is in B. Return the full values of those rows. 

## 3D example 
A3 = rand(1000,10,100); 
A3[indices,1,1] = b; 
Ared3 = A3[findin(A[:,1,1], b),:,:]; 
julia> size(Ared3) 
(100,10,100) 
+0

感谢您的快速回答! 你写道,“A的100个随机行现在有他们的第一个元素匹配b的一个元素”是那些不是以前匹配的那些行? – Hainmueck

+0

@Hainmueck这只是为了创造比赛可以在第一时间发生的情况。换句话说,因为我实际上没有访问你正在使用的矩阵“A”和矢量“b”,所以我需要模拟一个情况,其中将会有一个矩阵“A”,它与矢量'b'。如果没有这个,如果我刚开始使用随机的'A'和随机的'b',那么很可能存在很多(如果有的话)的比赛(取决于我如何进行随机抽签)。 –

+0

@Hainmueck换句话说,这些线条就是我的工作,为你制作一个最小可重现的例子;您可以在将来将自己的问题纳入其中。请参阅[这里](http://stackoverflow.com/help/mcve)了解更多细节。 –

0

你的逻辑是罚款,并会工作若B是一个向量。其原因并不在于你可能试图使用二维数组(即等级2)进行索引,而这恰好只有一列,而不是向量(即等级1)数组。即我敢肯定,如果你做size(b)结果将是(2,1)而不是(2,)这应该是。

如果您获得b的相应向量(例如collect(b)),您的索引操作应该可以正常工作。

实施例:

julia> A = rand(Int64[1,10],3,4,2) 
3x4x2 Array{Int64,3}: 
[:, :, 1] = 
10 10 1 10 
10 10 10 10 
    1 10 10 1 

[:, :, 2] = 
1 10 10 1 
1 10 1 1 
1 1 10 10 

julia> b = [1; 3] # this will work. NOTE THE RESULTING TYPE! 
2-element Array{Int64,1}: 
1 
3 

julia> A[b,:,:] 
2x4x2 Array{Int64,3}: 
[:, :, 1] = 
10 10 1 10 
    1 10 10 1 

[:, :, 2] = 
1 10 10 1 
1 1 10 10 

julia> c = [1 3]' # this will not. NOTE THE RESULTING TYPE 
2x1 Array{Int64,2}: 
1 
3 

julia> A[c,:,:] 
ERROR: MethodError: `index_shape_dim` has no method matching  index_shape_dim(::Array{Int64,3}, ::Int64, ::Array{Int64,2}, ::Colon, ::Colon) 

julia> A[collect(c),:,:] # this will work again, c is now a vector 
2x4x2 Array{Int64,3}: 
[:, :, 1] = 
10 10 1 10 
    1 10 10 1 

[:, :, 2] = 
1 10 10 1 
1 1 10 10