【问题标题】:How to change p-value of Numpy.random.choice based on position in array?如何根据数组中的位置更改 Numpy.random.choice 的 p 值?
【发布时间】:2020-06-18 14:24:57
【问题描述】:

我有一个大小为 NxNxN 的 3D 数组。我想用随机布尔值填充这个数组,我可以这样做:

a = np.random.choice([False,True],size=(N,N,N))

但是,我希望根据元素在数组中的位置来选择 True 或 False 的可能性(或 p 值)。我想也许我可以使用 p-value 参数来做到这一点,但只有这样才能选择为整个数组选择 True/False 的频率。

有没有办法为整个 (N,N,N) 数组设置特定的 p 值?我猜这将相当于一个 (N,N,N,2) 数组,额外的 2 用于 False 的 p 值和 True 的 p 值(尽管 p_True = 1 - p_False)。我觉得有一种我没有想到的更简单的方法。

编辑: 所以说我想创建一个简单的数组a,形状为(1,2)(只有两个元素,但故意多维)。我想用 True/False 填充这两个元素。我有另一个数组,其中填充了我希望这些元素为 False 的可能性或 p 值,例如 p_False,其中 p_False.shape = (1,2)。假设我希望第一个元素有 25% 的可能性为 False,但第二个元素有 50% 的可能性为假,那么 p_False = np.array([0.25,0.5])。

我尝试了一些类似的东西:

a = np.random.choice([[False,True],[False,True]],p=[[.25,.75],[.5,.5]])

但我得到一个 ValueError: a must be 1-dimensional。

【问题讨论】:

  • 你能详细说明to be based on the element's position in the array吗?也许使用一个小的 2D (N,N) 数组来演示?

标签: numpy random


【解决方案1】:

要生成不同概率的数组,可以使用以下代码:

# define an initial value of N
N = 512

# generate an array of probabilities. You can eventually build your own, since the size is respected
prob_array = np.array((range(0,N*N*N)))

# rescale the probabilities between 0 and 1
prob_array = (prob_array - np.min(prob_array)) / (np.max(prob_array) - np.min(prob_array))

# generate the random based on the probabilities, cast to booleans and reshape
np.reshape(np.array(np.random.binomial(1, p=prob_array, size=N*N*N), dtype=bool), (N,N,N))

这会生成一个数组,开头有很多 False,最后有很多 True:

array([[[False, False, False, ..., False, False, False],
        [False, False, False, ..., False, False, False],
        [False, False, False, ..., False, False, False],
        ...,
        [False, False, False, ..., False, False, False],
        [False, False, False, ..., False, False, False],
        [False, False, False, ..., False, False, False]],

       ...,


       [[ True,  True,  True, ...,  True,  True,  True],
        [ True,  True,  True, ...,  True,  True,  True],
        [ True,  True,  True, ...,  True,  True,  True],
        ...,
        [ True,  True,  True, ...,  True,  True,  True],
        [ True,  True,  True, ...,  True,  True,  True],
        [ True,  True,  True, ...,  True,  True,  True]]])

【讨论】:

  • 所以这看起来像是在 python 中循环遍历数组的每个元素,对吗?我实际的 NxNxN 数组的大小可能为 512x512x512,因此可能会很慢。我尝试使用 N=64 并不断收到错误:ValueError: probabilities are not non-negative。 N>5 时出现此错误。此外,当 N=5 时,我总是得到相同的答案,前四行都是 True,第 5 行都是 False。
  • 是的,大 N 可能会很慢。产生错误是因为 NNN 大于 100,因此 1 - 大于 100 的元素将生成负数概率,什么是不可能的。
  • 已更新以裁剪概率并生成没有循环的数据。
【解决方案2】:

对 [0, 1] 中的数字数组使用 binomial 方法。这是一个示例,它根据随机选择的概率将每个元素设置为 0 或 1:

import numpy
gen=numpy.random.Generator(numpy.random.PCG64())
ret=gen.binomial(1, gen.uniform(size=(3, 3, 3)))

如果你希望每个项目都是 True 或 False 而不是 0 或 1,恐怕我不知道该怎么做。

请注意,numpy.random.Generatorintroduced in NumPy 1.7。建议您使用最新版本的 NumPy;同时,您可以使用以下内容:

import numpy
ret=numpy.random.binomial(1, numpy.random.uniform(size=(3, 3, 3)))

【讨论】:

  • 看起来生成器可能是新的。我有 Numpy 1.15.1,但似乎没有。我分发此代码,所以我想要一些不需要更新 Numpy 版本的东西。有没有说 RandomState 或其他东西的替代品?
  • 是的;生成器是在 Numpy 1.7 中引入的。建议您使用最新版本的 Numpy;同时,您可以使用numpy.random.binomial/.uniform
猜你喜欢
  • 2022-01-08
  • 2021-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-10
相关资源
最近更新 更多