2016-07-26 213 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