1

我有一个 2D numpy 数组,它的 (N,N) 大小只有 0。我随机想在这个数组中插入 12 个 1,同时保持对角线位置的值等于 0。到目前为止我尝试过的是:

import numpy as np
def func(N=20):
    x= np.zeros((N,N))
    for m in range(N):
        for n in range(N):
                if m == n:
                    x[m][n] == 0
                else:
                    if np.count_nonzero(x) <= 12:
                            x.fill(1)
                            return (np.count_nonzero)
    print (x)

我得到的输出是一个充满 1 的 N,N 数组。数量达到 12 个后,我无法停止插入 1。我该如何解决?

4

1 回答 1

1

由于您使用的是 NumPy,并且如果您对替代的矢量化解决方案没问题,这里有一个带有掩码并选择这些地方的np.random.choice-

def random_off_diag_fill(N, num_rand = 12, fillval=1):
    # Initialize array
    x= np.zeros((N,N),dtype=type(fillval))

    # Generate flat nondiagonal indices using masking
    idx = np.flatnonzero(~np.eye(N,dtype=bool))

    # Select num_rand random indices from those and set those
    # in a flattened view of the array to be as fillval
    x.ravel()[np.random.choice(idx, num_rand, replace=0)] = fillval
    return x

样品运行 -

In [57]: random_off_diag_fill(N=8, num_rand=12, fillval=1)
Out[57]: 
array([[0, 0, 0, 0, 0, 1, 1, 0],
       [0, 0, 0, 0, 0, 0, 0, 0],
       [1, 0, 0, 0, 0, 0, 1, 1],
       [0, 0, 0, 0, 0, 0, 0, 0],
       [1, 1, 0, 0, 0, 1, 0, 0],
       [0, 0, 1, 0, 1, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0],
       [1, 0, 1, 0, 0, 0, 0, 0]])

In [63]: random_off_diag_fill(N=5, num_rand=12, fillval=2.45)
Out[63]: 
array([[ 0.  ,  0.  ,  0.  ,  0.  ,  2.45],
       [ 2.45,  0.  ,  2.45,  0.  ,  2.45],
       [ 0.  ,  2.45,  0.  ,  2.45,  2.45],
       [ 2.45,  2.45,  0.  ,  0.  ,  0.  ],
       [ 2.45,  2.45,  0.  ,  2.45,  0.  ]])
于 2017-06-03T15:41:53.370 回答