2015-05-15 37 views
2

我有形狀a.shape = (1,k*d)一個numpy的陣列,我想將其與形狀b.shape = (k*d,k)在每列改變numpy的陣列的格式與沒有循環

b[i,j] = a[i] if j<i+1

b[i,j] = 0 if not

變換到numpy的陣列例如:

k = 3 
d= 2 
********** 

A = |a| => B = |a 0 0| 
    |b|   |b 0 0| 
    |c|   |0 c 0| 
    |d|   |0 d 0| 
    |e|   |0 0 e| 
    |f|   |0 0 f| 

主要是,沒有循環!

我正在尋找的是一系列numpy-matrix操作,可以產生所需的結果。

回答

4

這再現了你的例子。它可以推廣到其它kd

In [12]: a=np.arange(6)  
In [13]: b=np.zeros((6,3)) 
In [14]: b[np.arange(6),np.arange(3).repeat(2)]=a 

In [15]: b 
Out[15]: 
array([[ 0., 0., 0.], 
     [ 1., 0., 0.], 
     [ 0., 2., 0.], 
     [ 0., 3., 0.], 
     [ 0., 0., 4.], 
     [ 0., 0., 5.]]) 

的關鍵是列索引的是重複的所需次數

In [16]: np.arange(3).repeat(2) 
Out[16]: array([0, 0, 1, 1, 2, 2]) 
1

下面是基於零填充到所述輸入陣列的有效方法。每個代碼步驟中的內聯註釋必須使其更清楚地說明如何實現所需的輸出。下面的代碼 -

# Arrange groups of d number of elements from the input array into 
# rows of a 2D array and pad with k*d zeros in each row. 
# Thus, the shape of this 2D array would be (k,d+k*d) 
A_zeroappend = np.zeros((k,(k+1)*d)) 
A_zeroappend[:,:d] = A.reshape(-1,d) 

# Get rid of the last row of appended zeros. 
# Reshape and transpose to desired output shape (k*d,k) 
out = A_zeroappend.ravel()[:k*k*d].reshape(-1,k*d).T 

運行測試

這裏有一個快速運行的測試比較所提出的方法,並在other answer列出的np.repeat基礎的方法 -

In [292]: k = 800 
    ...: d = 800 
    ...: A = np.random.randint(2,9,(1,k*d)) 
    ...: 

In [293]: %%timeit 
    ...: B = np.zeros((k*d,k)) 
    ...: B[np.arange(k*d),np.arange(k).repeat(d)]=A 
    ...: 
1 loops, best of 3: 342 ms per loop 

In [294]: %%timeit 
    ...: A_zeroappend = np.zeros((k,(k+1)*d)) 
    ...: A_zeroappend[:,:d] = A.reshape(-1,d) 
    ...: out = A_zeroappend.ravel()[:k*k*d].reshape(-1,k*d).T 
    ...: 
100 loops, best of 3: 3.07 ms per loop 

好像所提出的方法太快了!

+0

這就是完美!多謝,夥計 – farhawa