用随机数替换条件下的numpy数组值

Posted

技术标签:

【中文标题】用随机数替换条件下的numpy数组值【英文标题】:Replace numpy array value on condition with random number 【发布时间】:2017-07-19 22:26:59 【问题描述】:

我需要根据条件用随机数替换 numpy 数组中的一些值。

我有一个函数可以在 50% 的时间内添加随机值:

def add_noise(noise_factor=0.5):

    chance = random.randint(1,100)
    threshold_prob = noise_factor * 100.

    if chance <= threshold_prob:
        noise = float(np.random.randint(1,100))
    else:
        noise = 0.

    return(noise)

但是当我调用 numpy 函数时,它会将所有匹配值替换为生成的随机数:

np.place(X, X==0., add_noise(0.5))

这样做的问题是 add_noise() 只运行一次,它将所有 0. 值替换为噪声值。

我要做的是“迭代” numpy 数组中的每个元素,检查条件(是否 ==0。),我想每次都通过 add_noise() 生成噪声值。

我可以通过遍历每一行和每一列的 for 循环来做到这一点,但有人知道更有效的方法吗?

【问题讨论】:

发布的解决方案是否适合您? 是的,矢量化方法很好。谢谢。 【参考方案1】:

你可以对你的函数进行矢量化,这样可以很容易地应用于每个元素,而且我想效率也很高。

import random
import numpy as np

def add_noise(x):
    if not x:
        if random.random() <= 0.5:
            noise = float(np.random.randint(1,100))
            return noise
        else:
            return 0
    else:
        return x

x = np.zeros(shape=(10, 10))

n = np.vectorize(add_noise)
x = n(x)

【讨论】:

【参考方案2】:

这是一种矢量化方法 -

noise_factor = 0.5 # Input param

# Get mask of zero places and the count of it. Also compute threshold
mask = X==0
c = np.count_nonzero(mask)
threshold_prob = noise_factor * 100.

# Generate noise numbers for count number of times. 
# This is where vectorization comes into the play.
nums = np.random.randint(1,100, c)

# Finally piece of the vectorization comes through replacing that IF-ELSE
# with np,where that does the same op of choosing but in a vectorized way
vals = np.where(nums <= threshold_prob, np.random.randint(1,100, c) , 0)

# Assign back into X
X[mask] = vals

额外的好处是我们将0smask 重新用于add_noise 操作,也用于分配回X。这取代了np.place 的使用,是一种效率标准。

进一步提升性能

我们可以在计算 numsvals 的步骤中进一步优化,这些步骤使用两个随机数生成步骤,而是这样做一次并在第二步重复使用,就像这样 -

nums = np.random.randint(1,100, (2,c))
vals = np.where(nums[0] <= threshold_prob, nums[1] , 0)

【讨论】:

【参考方案3】:

如果我理解正确,您想根据两个条件将 numpy 数组的值更改为随机值。

    值应该为零 一些随机的机会因素

对于这两个条件,您可以创建两个掩码并将它们与np.logical_and 组合。并且您可以使用np.random 方法获取随机数数组。

import numpy as np

def add_perhaps_noise_if_zero(x, threshold=0.5):
    mask_1 = x == 0.0
    mask_2 = np.random.random(x.shape) <= threshold
    mask_combined = np.logical_and(mask_1, mask_2)
    x[mask_combined] += np.random.random(x.shape)[mask_combined]
    return x


x = np.zeros((5,5))
for i in range(5):
    print(x)
    x = add_perhaps_noise_if_zero(x)

【讨论】:

以上是关于用随机数替换条件下的numpy数组值的主要内容,如果未能解决你的问题,请参考以下文章

Python中的高效数组替换

numpy 随机数使用

我可以用Numpy制作随机面具吗?

numpy 排序,随机数,保留小数

11-2 numpy/pandas/matplotlib模块

生成带有条件的随机数列表 - numpy [重复]