简体   繁体   English

使用Numpy / Python将概率函数分别应用于数组的特定元素

[英]Applying a probabilistic function over specific element of an array individually with Numpy/Python

I'm fairly new to Python/Numpy. 我是Python / Numpy的新手。 What I have here is a standard array and I have a function which I have vectorized appropriately. 我这里有一个标准数组,并且我有一个已适当向量化的函数。

def f(i):
     return np.random.choice(2,1,p=[0.7,0.3])*9
f = np.vectorize(f)

Defining an example array: 定义示例数组:

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

With the vectorized function, f, I would like to evaluate f on each cell on the array with a value of 0. 使用向量化函数f,我想对数组上每个单元的f赋值为0。

I am trying to leave for loops as a last resort. 我试图离开循环作为最后的手段。 My arrays will eventually be larger than 100 by 100, so running each cell individually to look and evaluate f might take too long. 我的数组最终将大于100 x 100,因此单独运行每个单元以查找和评估f可能会花费太长时间。

I have tried: 我努力了:

print f(array[array==0])

Unfortunately, this gives me a row array consisting of 5 elements (the zeroes in my original array). 不幸的是,这给了我一个由5个元素组成的行数组(原始数组中的零)。

Alternatively I have tried, 或者,我尝试过

array[array==0] = f(1)

But as expected, this just turns every single zero element of array into 0's or 9's. 但是,正如预期的那样,这只是将数组的每个零元素变为0或9。

What I'm looking for is somehow to give me my original array with the zero elements replaced individually. 我正在寻找的是以某种方式给我我的原始数组,其中零元素被单独替换。 Ideally, 30% of my original zero elements will become 9 and the array structure is conserved. 理想情况下,原始零元素的30%将变为9,并且数组结构是守恒的。

Thanks 谢谢

The reason your first try doesn't work is because the vectorized function handle, let's call it f_v to distinguish it from the original f , is performing the operation for exactly 5 elements: the 5 elements that are returned by the boolean indexing operation array[array==0] . 你的第一次尝试不工作的原因是因为矢量化功能手柄,让我们把它f_v从原来的区别f ,是整整 5个元素进行操作:由布尔索引操作返回的5个元素array[array==0] That returns 5 values, it doesn't set those 5 items to the returned values. 返回 5个值,它不设置那些5项返回值。 Your analysis of why the 2nd form fails is spot-on. 您对第二种形式失败的原因的分析是认真的。

If you wanted to solve it you could combine your second approach with adding the size option to np.random.choice : 如果您想解决该问题,可以将第二种方法与在np.random.choice添加size选项结合np.random.choice

array = np.array([[1,1,0],[0,1,0],[0,0,1]])
mask = array==0
array[mask] = np.random.choice([18,9], size=mask.sum(), p=[0.7, 0.3])
# example output:
# array([[ 1,  1,  9],
#        [18,  1,  9],
#        [ 9, 18,  1]])

There was no need for np.vectorize : the size option takes care of that already. 不需要np.vectorizesize选项已经解决了这一问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM