2017-07-06 22 views
1

可以說我有一個簡單的數組:如何矩陣不等長的項目組值

a = np.arange(3) 

和指數的相同長度的數組:

I = np.array([0, 0, 1]) 

我現在想根據指數對值進行分組。 如何將第一個數組的元素分組以產生下面的結果?

np.array([[0, 1], [2], dtype=object) 

這裏是我的嘗試:

a = np.arange(3) 
I = np.array([0, 0, 1]) 
out = np.empty(2, dtype=object) 
out.fill([]) 

aslists = np.vectorize(lambda x: [x], otypes=['object']) 

out[I] += aslists(a) 

然而,這種方法沒有並置的名單,但只維持每個索引的最後一個值:

array([[1], [2]], dtype=object) 

或者,對於2維情況:

a = np.random.rand(100) 
I = (np.random.random(100) * 5 //1).astype(int) 
J = (np.random.random(100) * 5 //1).astype(int) 

out = np.empty((5, 5), dtype=object) 
out.fill([]) 

如何根據兩個索引數組附加項目?

+0

目前它不是,但我可以排序,是 –

回答

1

1D案例

假設I進行排序,如輸出數組列表 -

idx = np.unique(I, return_index=True)[1] 
out = np.split(a,idx)[1:] 

另一個與slicing得到idx分裂a -

out = np.split(a, np.flatnonzero(I[1:] != I[:-1])+1) 

要獲得一系列列表作爲輸出 -

np.array([i.tolist() for i in out]) 

樣品運行 -

In [84]: a = np.arange(3) 

In [85]: I = np.array([0, 0, 1]) 

In [86]: out = np.split(a, np.flatnonzero(I[1:] != I[:-1])+1) 

In [87]: out 
Out[87]: [array([0, 1]), array([2])] 

In [88]: np.array([i.tolist() for i in out]) 
Out[88]: array([[0, 1], [2]], dtype=object) 

2D情況

對於2D情況下填充到2D陣列與來自索引在兩個陣列IJ表示由分組中的要分配組的行和列,我們可以做類似的事情這 -

ncols = 5 
lidx = I*ncols+J 
sidx = lidx.argsort() # Use kind='mergesort' to keep order 
lidx_sorted = lidx[sidx] 
unq_idx, split_idx = np.unique(lidx_sorted, return_index=True) 
out.flat[unq_idx] = np.split(a[sidx], split_idx)[1:] 
+0

好的解決方案!對於我最終的應用程序,我正在尋找類似的東西,但我的輸出數組是二維的,並且我有兩個維度的索引數組:I = np.array([0,0,1]); J = np.array([1,0,0]); out = np.empty((2,2),dtype = object)。你碰巧也知道這個解決方案嗎? –

+0

@JohnDamen所以,我們需要用零或其他無效的說明符填充不可用的那些?我猜測輸出會是這樣的:'[[0,1] [2,NA]]? – Divakar

+0

這些名單可能不均衡,主要觀點是沿着兩個維度的指數分組 –