在Python中,如何将一组数字随机分布到网格/矩阵上?

在Python中,如何将一组数字随机分布到网格/矩阵上?,python,numpy,random,Python,Numpy,Random,我有以下问题: 我想通过从给定列表([-1,0,1,2])中填充数字来生成100x100网格(numpy.ndarray)。我想在这个网格上随机分配它们。此外,数字必须保持以下比率:数字0必须占据网格的10%,而其余数字各有30%的比率,因此它们的总和等于100%。使用np.random.choice()我能够生成随机数,每个随机数都以相关概率分布。但是,我遇到了问题,因为我必须确保数字0精确地占整个网格的10%,而非零数字精确地占每个网格的30%。使用np.random.choice() im

我有以下问题: 我想通过从给定列表(
[-1,0,1,2]
)中填充数字来生成100x100网格(
numpy.ndarray
)。我想在这个网格上随机分配它们。此外,数字必须保持以下比率:数字0必须占据网格的10%,而其余数字各有30%的比率,因此它们的总和等于100%。使用
np.random.choice()
我能够生成随机数,每个随机数都以相关概率分布。但是,我遇到了问题,因为我必须确保数字0精确地占整个网格的10%,而非零数字精确地占每个网格的30%。使用
np.random.choice()

import numpy as np

numbers = np.random.choice([-1,0,1,2],(100,100),p=[0.3,0.1,0.3,0.3])
print(np.count_nonzero(numbers)) #must be = 0.1 always!
我的另一个想法是,最初将整个矩阵设置为
np.zeros((100100))
,然后仅用90%的非零元素填充,然而,我不知道如何处理这个问题,使数字在网格上随机分布,即随机位置/索引


编辑:网格中每个非零数的比率将仅取决于我希望为空的单元格数量,或者在这种情况下为0。所有其他非零元素必须具有相同的比率。例如,我希望网格的20%为零,剩余的数字的比率为(1-零的比率)/非零元素的数量。

这应该满足您的要求(由RemcoGerlich建议),尽管我不知道这种方法的效率有多高:

import numpy as np

# Constants
SHAPE = (100, 100)
LENGTH = SHAPE[0] * SHAPE[1]

REST = [-1, 1, 2]
ZERO_PROB = 10
BASE_PROB = (100 - ZERO_PROB) // len(REST)

NUM_ZERO = round(LENGTH * (ZERO_PROB / 100))
NUM_REST = round(LENGTH * (BASE_PROB / 100))

# Make base 1D array
base_arr = [0 for _ in range(NUM_ZERO)]
for i in REST:
    base_arr += [i for _ in range(NUM_REST)]
base_arr = np.array(base_arr)

# Give it a random order
np.random.shuffle(base_arr)

# Finally, reshape the array
result_arr = base_arr.reshape(SHAPE)
看看你的评论,我想这取决于有多少数字具有不同的概率。您可以只使用一个for循环,该循环遍历并使数组的长度与每个数组的长度相匹配,以添加到
基本数组中。当然,这也可以是一个传递变量的函数,而不仅仅是一个带有硬编码常量的脚本


根据注释进行编辑。

关键是制作一个1D、长度为10000的数组,每个数组都有正确的选择数,然后np.random.shuffle()对其进行编辑。然后将其重塑为100x100阵列。@RemcoGerlich谢谢,这正是我想要的这个特定示例。但是,如何使其更灵活,即,如果我想要分发的数字数量正在发生变化,比如下次我需要在1000x1000网格上分发12个数字?在这种情况下,我需要应用for循环,对吗?(请注意,数字的实际值是无关的,我只需要它们是可区分的)比率实际上只取决于我希望有多少单元格为空,或者在这种情况下为0。所有其他非零元素必须具有相同的比率。假设我想让20%的网格为零,剩下的数字的比率为(1-ratio of zero)/amount of non-zero元素。我基于此编辑了它,这更符合你的要求吗?谢谢你的方法,这对我来说很好。这也代表了@RemcoGerlich提出的想法,所以谢谢你们。我还考虑过使用for循环创建长度相同但值不同的数组,但随后使用
np。将它们连接在一起。然后,通过应用
np.random.schuffle(base_arr)
我得到了一个具有精确比率但随机顺序的向量。如果想要转换成矩阵,可以使用
np.reformate()
。这样,也可以使用
plt.pcolormesh
绘制该矩阵/网格。