如何更改numpy数组中的随机索引位置

How to change random index positions in numpy array

我有一个像这样的 numpy 数组:

array([[0.5, 0.2, 0.6],
       [0.8, 0.1, 0.3],
       [0.4, 0.5, 0.4],
       [0.3, 0.2, 0.9]])

我想将第 3 列中 50% 的值更改为随机值。我怎样才能有效地做到这一点?此操作将不得不执行数十万次,因此效率在这里非常重要。输出可能如下所示:

array([[0.5, 0.2, 0.2],
       [0.8, 0.1, 0.3],
       [0.4, 0.5, 0.4],
       [0.3, 0.2, 0.1]])

我首先想到的是将这一列隔离开来,然后替换掉一些值,再将这一列移回原来的矩阵中。

last_column = array[:,2]
last_column = change_values_randomly(last_column)
np.c_[array[:,:2], last_column]

如何随机更改这些值的 50%?

使用numpy.random.permutation生成不重复的随机索引,取前半部分,然后用相同大小的随机数组赋值:

>>> r = np.array([[0.5, 0.2, 0.6],
... [0.8, 0.1, 0.3],
... [0.4, 0.5, 0.4],
... [0.3, 0.2, 0.9]])
>>> last = r[:, -1]
>>> last[np.random.permutation(last.size)[:last.size // 2]] = np.random.rand(last.size // 2)
>>> r
array([[0.5       , 0.2       , 0.6       ],
       [0.8       , 0.1       , 0.56898452],
       [0.4       , 0.5       , 0.4       ],
       [0.3       , 0.2       , 0.67314702]])

试试这个

arr = np.array([[0.5, 0.2, 0.6],
[0.8, 0.1, 0.3],
[0.4, 0.5, 0.4],
[0.3, 0.2, 0.9]])
# randomly select rows 
rows = np.random.choice(4, size=2, replace=False)
# replace values in the last column with random values
arr[rows, 2] = np.random.rand(2)
arr
array([[0.5       , 0.2       , 0.81496687],
       [0.8       , 0.1       , 0.3       ],
       [0.4       , 0.5       , 0.18514918],
       [0.3       , 0.2       , 0.9       ]])

使用生成器 api 比 np.random.choice

快得多
rows = np.random.default_rng().choice(length, size=half, replace=False)
arr[rows, 2] = np.random.rand(2)

基准:

arr = np.linspace(0,1,300000).reshape(-1,3)
length = len(arr)
half = length//2

%timeit np.random.default_rng().choice(length, size=half, replace=False)
# 2.31 ms ± 808 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit np.random.permutation(length)[:half]
# 4.14 ms ± 313 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit np.random.choice(length, size=half, replace=False)
# 4.14 ms ± 313 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit np.random.default_rng().permutation(length)[:half]
# 3.69 ms ± 173 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

您可以使用:

n = a.shape[0]
idx = np.random.choice(np.arange(n), size=n//2, replace=False)
a[idx, 2] = -1 # or for random:  np.random.rand(n)

示例输出:

[[ 0.5  0.2 -1. ]
 [ 0.8  0.1  0.3]
 [ 0.4  0.5 -1. ]
 [ 0.3  0.2  0.9]]