2014-10-11 169 views
6

我有一個整數的二維數組,我們將它稱爲「A」。快速計算隨機3D numpy陣列從2D numpy陣列

我想創建所有的1和0,使得一個3維陣列 「B」:

  • 對於任何固定的(I,J)sum(B[i,j,:])==A[i.j],即,B[i,j,:]包含A[i,j]1s在它
  • 1是隨機放置在第三維。

我知道如何使用標準的python索引來做這件事,但事實證明這很慢。

我正在尋找一種方式來做到這一點,利用可以使Numpy快速的功能。

這是我將如何使用標準索引做到這一點:

B=np.zeros((X,Y,Z)) 
indexoptions=range(Z) 

for i in xrange(Y): 
    for j in xrange(X): 
     replacedindices=np.random.choice(indexoptions,size=A[i,j],replace=False) 
     B[i,j,[replacedindices]]=1 

能有人請解釋我怎麼能以更快的方式做到這一點?

編輯:下面是一個例子 「A」:

A=np.array([[0,1,2,3,4],[0,1,2,3,4],[0,1,2,3,4],[0,1,2,3,4],[0,1,2,3,4]]) 
在這種情況下

X = Y = 5和Z> = 5

+1

試圖在這方面取得進展,我問了一個更簡單的問題:http://stackoverflow.com/questions/26310897/numpy-create-bool-array-like-repeat-but-in-multiple-dimensions - 但後來我意識到我計劃的'np.random.shuffle(np.rollaxis(B,2))'不會獨立地混洗所有的行,所以這還不是一個好答案。積木,也許吧。 :) – 2014-10-11 04:22:41

回答

4

基本上相同的思路@JohnZwinck和@DSM,但用shuffle功能洗牌給定軸:

import numpy as np 

def shuffle(a, axis=-1): 
    """ 
    Shuffle `a` in-place along the given axis. 

    Apply numpy.random.shuffle to the given axis of `a`. 
    Each one-dimensional slice is shuffled independently. 
    """ 
    b = a.swapaxes(axis,-1) 
    # Shuffle `b` in-place along the last axis. `b` is a view of `a`, 
    # so `a` is shuffled in place, too. 
    shp = b.shape[:-1] 
    for ndx in np.ndindex(shp): 
     np.random.shuffle(b[ndx]) 
    return 


def random_bits(a, n): 
    b = (a[..., np.newaxis] > np.arange(n)).astype(int) 
    shuffle(b) 
    return b 


if __name__ == "__main__": 
    np.random.seed(12345) 

    A = np.random.randint(0, 5, size=(3,4)) 
    Z = 6 

    B = random_bits(A, Z) 

    print "A:" 
    print A 
    print "B:" 
    print B 

輸出:

A: 
[[2 1 4 1] 
[2 1 1 3] 
[1 3 0 2]] 
B: 
[[[1 0 0 0 0 1] 
    [0 1 0 0 0 0] 
    [0 1 1 1 1 0] 
    [0 0 0 1 0 0]] 

[[0 1 0 1 0 0] 
    [0 0 0 1 0 0] 
    [0 0 1 0 0 0] 
    [1 0 1 0 1 0]] 

[[0 0 0 0 0 1] 
    [0 0 1 1 1 0] 
    [0 0 0 0 0 0] 
    [0 0 1 0 1 0]]] 
+0

哼。我討厭'shuffle'不像我想的那樣工作。通過重塑成一個較低D的對象並對其進行洗牌,可以避免Python級別的循環嗎? – DSM 2014-10-11 04:54:30

+1

@DSM:我分享你的煩惱!我找不到一種方法通過一次調用'np.random.shuffle'來完成這項工作。 (我的第一個版本'shuffle' - 這裏沒有顯示 - 是一個向量化的Fisher-Yates算法,但它不像這個那麼清晰,並且當非軸向尺寸很小時可能慢很多。 ) – 2014-10-11 05:01:38

+0

謝謝!對於大型數組,這種方法比我原來的方法快100倍以上。 – nickexists 2014-10-11 08:53:16