2014-10-11 152 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