Python Numpy:替换数组中的随机元素

Python Numpy:替换数组中的随机元素,python,numpy,random,Python,Numpy,Random,我已经在谷歌上搜索了一下,没有找到任何好的 答案 问题是,我有一个2d numpy数组,我想 在随机位置替换其某些值 我使用numpy.random.choice创建了一些答案 阵列的掩码。不幸的是,这并没有造成 原始数组上的视图,因此无法替换其值 这是我想做的一个例子 假设我有一个带有浮点值的二维数组 [[ 1., 2., 3.], [ 4., 5., 6.], [ 7., 8., 9.]] 然后我想替换任意数量的 元素。如果我能用一个参数来调整,那就太好了 要替换多少个元素。 可能的结

我已经在谷歌上搜索了一下,没有找到任何好的 答案

问题是,我有一个2d numpy数组,我想 在随机位置替换其某些值

我使用numpy.random.choice创建了一些答案 阵列的掩码。不幸的是,这并没有造成 原始数组上的视图,因此无法替换其值

这是我想做的一个例子

假设我有一个带有浮点值的二维数组

[[ 1., 2., 3.],
 [ 4., 5., 6.],
 [ 7., 8., 9.]]
然后我想替换任意数量的 元素。如果我能用一个参数来调整,那就太好了 要替换多少个元素。 可能的结果如下所示:

[[ 3.234, 2., 3.],
 [ 4., 5., 6.],
 [ 7., 8., 2.234]]
[[ 1.          2.          3.        ]
 [ 4.          5.          8.54749399]
 [ 7.57749917  8.          4.22590641]]
我想不出一个好办法来完成这件事。 谢谢你的帮助

编辑


感谢您的快速回复。

这不是真正的优化,而是帮助您找到解决方法的起点:

import numpy as np

a = np.array( [[ 1., 2., 3.], [ 4., 5., 6.], [ 7., 8., 9.]])

def replace(ar,nbr):
  x,y = ar.shape
  s = x*y 
  mask = [1]*nbr + [0]*(s-nbr)
  np.random.shuffle(mask)
  mask = np.array(mask) == 1
  ar.reshape( (s) )[mask] = [ np.random.random() for _ in range(nbr) ]

您可以使用scipy创建bernoulli随机变量,参数p将控制最终替换数组中值的百分比。然后根据伯努利随机变量的值是0还是1替换原始数组中的值

from scipy.stats import bernoulli as bn
import numpy as np

array = np.array([[ 1., 2., 3.],[ 4., 5., 6.],[ 7., 8., 9.]])
np.random.seed(123)
flag = bn.rvs(p=0.5,size=(3,3))
random_numbers = np.random.randn(3,3)
array[flag==0] = random_numbers[flag==0]

您始终可以随机生成
n
整数,为数组的展开视图(1D版本)编制索引,并将这些索引值设置为
n
随机值:

In [1]: import numpy as np
In [2]: x = np.arange(1, 10).reshape(3, 3).astype(float)
In [3]: m = np.product(x.shape)
In [4]: n = 3
In [5]: x.ravel()[np.random.randint(0, m, size=n)] = np.random.rand(n)
In [6]: x
Out[6]: 
array([[ 0.28548823,  0.28819589,  3.        ],
       [ 4.        ,  5.        ,  6.        ],
       [ 7.        ,  8.        ,  0.28772056]])
如果希望值大于1,可以按某个因子缩放随机生成的值;例如,
np.random.rand(n)*m将产生介于0和
np.product(x.shape)
之间的值


请注意,默认情况下在原地操作。

当数组为一维时,很容易随机选择索引,因此我建议将数组重塑为1D,更改随机元素,然后重塑为原始形状

例如:

import numpy as np

def replaceRandom(arr, num):
    temp = np.asarray(arr)   # Cast to numpy array
    shape = temp.shape       # Store original shape
    temp = temp.flatten()    # Flatten to 1D
    inds = np.random.choice(temp.size, size=num)   # Get random indices
    temp[inds] = np.random.normal(size=num)        # Fill with something
    temp = temp.reshape(shape)                     # Restore original shape
    return temp
所以这就像:

>>> test = np.arange(24, dtype=np.float).reshape(2,3,4)
>>> print replaceRandom(test, 10)
[[[  0.          -0.95708819   2.           3.        ]
  [ -0.35466096   0.18493436   1.06883205   7.        ]
  [  8.           9.          10.          11.        ]]
 [[ -1.88613449  13.          14.          15.        ]
  [  0.57115795  -1.25526377  18.          -1.96359786]
  [ 20.          21.           2.29878207  23.        ]]]

在这里,我替换了从正态分布中选择的元素,但是很明显,您可以用您想要的任何东西替换对
np.random.normal
的调用。

只需使用相同形状的随机数组来屏蔽您的输入数组

import numpy as np

# input array
x = np.array([[ 1., 2., 3.], [ 4., 5., 6.], [ 7., 8., 9.]])

# random boolean mask for which values will be changed
mask = np.random.randint(0,2,size=x.shape).astype(np.bool)

# random matrix the same shape of your data
r = np.random.rand(*x.shape)*np.max(x)

# use your mask to replace values in your input array
x[mask] = r[mask]
产生如下结果:

[[ 3.234, 2., 3.],
 [ 4., 5., 6.],
 [ 7., 8., 2.234]]
[[ 1.          2.          3.        ]
 [ 4.          5.          8.54749399]
 [ 7.57749917  8.          4.22590641]]

我最喜欢这个。它很快,但不脏。要改变要替换的元素的预期数量,请使用
mask=np.random.choice([0,1],size=x.shape,p=((1-替换率),替换率)).astype(np.bool)
而不是上面的
randint
,这相当于使用上面的
np.random.choice
替换率=0.5