2014-10-11 25 views
6

gelen randomize 3D numpy dizi hesaplamak 2 boyutlu bir tam sayı dizisi var, biz buna "A" diyoruz. B[i,j,:] o içinde A[i,j]1s içeren, yani, herhangi bir sabit (i, j) içinhızlı bir şekilde 2B numpy dizi

  • sum(B[i,j,:])==A[i.j]:

    tüm 1s ve 0s bu şekilde bir 3-boyutlu bir dizi "B" oluşturmak isteyen

  • 1'ler rastgele 3. boyuta yerleştirilir.

Standart python indekslemeyi kullanarak bunu nasıl yapacağımı biliyorum, ancak bu çok yavaş oluyor.

Numpy'yi hızlı hale getirebilecek özelliklerden yararlanarak bunu yapmanın bir yolunu arıyorum.

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 

Birisi daha hızlı bir şekilde bunu nasıl açıklayabilir misiniz: Burada

Ben standart indeksleme kullanarak yapacağını nasıl?

Düzenleme: İşte bir örnek "A": Bu durumda

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 ve Z> = 5

+1

Bu konuda ilerleme kaydetmeye çalışıyorum, daha basit bir soru sordum: http://stackoverflow.com/questions/26310897/numpy-create-bool-array-like-repeat-but-in-multiple-dimensions - ama sonra ben planladığım np.random.shuffle (np.rollaxis (B, 2)) 'nin tüm satırları bağımsız olarak karıştırmadığını fark ettim, bu yüzden bu henüz bir cevap değil. Yapı taşları belki. :) –

cevap

4

Esasen @JohnZwinck ve @DSM, aynı fikri ancak

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 

Çıkış:

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]]] 
belirli bir eksen dağıtılması için bir shuffle fonksiyonlu
+0

Hmmph. Ben shuffle'ın yaptığı gibi düşünmediği için sinirlendim. Python düzeyinde döngü, bir alt-D nesnesine yeniden şekillendirilerek ve karıştırılarak önlenebilir mi? – DSM

+1

@DSM: Rahatsızlığınızı paylaşıyorum! Bu işi tek bir çağrı ile np.random.shuffle 'yapmak için bir yol bulamadım. ('Shuffle' - benim ilk versiyonum burada gösterilmemiştir - vectorized Fisher-Yates algoritmasıdır, ancak bu kadar net değildir ve eksen dışı boyutlar küçük olduğunda bu çok daha yavaştır.) –

+0

Teşekkürler! Büyük diziler için bu yöntem aslında yaptığımdan 100 kat daha hızlıdır. – nickexists