如何使用由数组每一行中的值确定的组合将 Numpy 数组的大小调整为 add/replace 行

How to resize a Numpy array to add/replace rows with combinations determined by the values in each row of the array

所以我有一个程序,它有时会创建随机数组,并且我执行了一个操作,即添加行,同时根据行中找到的值替换其他行。其中一个随机数组看起来像这样,但请记住,它的大小可能随机变化,范围从 3x3 到 10x10:

0 2 0 1
1 0 0 1
1 0 2 1
2 0 1 2

对于至少有一个值等于 2 的每一行,我需要 remove/replace 该行并添加更多行。添加的行数将取决于 0 和 1 的可能组合数,其中位数等于每行中计数的 2 数。每个添加的行都会在 2 所在的位置引入这些组合之一。我正在寻找的结果将如下所示:

0 1 0 1 # First combination to replace 0 2 0 1
0 0 0 1 # Second combination to replace 0 2 0 1 (Only 2 combinations, only one 2)
1 0 0 1 # Stays the same
1 0 1 1 # First combination to replace 1 0 2 1 
1 0 0 1 # Second combination to replace 1 0 2 1 (Only 2 combinations, only one 2)
0 0 1 0 # First combination to replace 2 0 1 2
0 0 1 1 # Second combination to replace 2 0 1 2
1 0 1 1 # Third combination to replace 2 0 1 2
1 0 1 0 # Fourth combination to replace 2 0 1 2 (4 combinations, there are two 2s)

如果您知道实现此目的的 Numpy 方法,我将不胜感激。

不是最漂亮的代码,但它完成了工作。您可以清理 itertools 调用,但这可以让您了解它是如何工作的。

import numpy as np
import itertools

X = np.array([[0, 2, 0, 1],
              [1, 0, 0, 1],
              [1, 0, 2, 1],
              [2, 0, 1, 2]])


def add(X_,Y):
    if Y.size == 0:
        Y = X_
    else:
        Y = np.vstack((Y, X_))
    return(Y)

Y = np.array([])
for i in range(len(X)):
    if 2 not in X[i,:]:
        Y = add(X[i,:], Y)
    else:
        a = np.where(X[i,:]==2)[0]
        n = [[i for i in itertools.chain([1, 0])] for _ in range(len(a))]
        m = list(itertools.product(*n))
        for j in range(len(m)):            
            M = 1 * X[i,:]
            u = list(m[j])
            for k in range(len(a)):
                M[a[k]] = u[k]
            Y = add(M, Y)

print(Y)
#[[0 1 0 1]
# [0 0 0 1]
# [1 0 0 1]
# [1 0 1 1]
# [1 0 0 1]
# [1 0 1 1]
# [1 0 1 0]
# [0 0 1 1]
# [0 0 1 0]]

您可以尝试以下方法。创建示例数组:

import numpy as np

np.random.seed(5)
a = np.random.randint(0, 3, (4, 4))
print(a)

这给出:

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

计算输出数组:

ts = (a == 2).sum(axis=1)
r = np.hstack([np.array(np.meshgrid(*[[0, 1]] * t)).reshape(t, -1).T.ravel() for t in ts if t])
out = np.repeat(a, 2**ts, axis=0)
out[out == 2] = r
print(out)

结果:

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