【问题标题】:Random values in numpy wherenumpy中的随机值在哪里
【发布时间】:2016-01-02 05:23:04
【问题描述】:

当条件为True 时,我正在尝试获取一系列随机选择的数字。

我有一个充满布尔数字的 NumPy 数组:

In [1]: multiples
Out[1]: array([False, False, False,  True,  True, 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, False, False, False,
               False, False, False,  True,  True, False,  True,  True, False,
               False, False, False,  True,  True, 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, False,
               False, False, False, False,  True,  True,  True, False,  True,
                True, False, False, False,  True,  True, False], dtype=bool)

我想根据条件将其转换为值数组:

如果值为True,则返回从[-1, 0, 1] 中随机选择的数字,或者返回0

所以在上面的例子中,我想输出如下:

Out[2]: array([ 0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                0,  0,  0,  0,  0,  0, -1,  0,  0, -1,  0,  0,  0,  0, -1,  1,  0,
                0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -1,  1,  0,  0,  0,  0,  0,
                1, -1, -1,  0,  1,  0,  0,  0,  0,  0,  0,  0])

numpy.where() 几乎给了我想要的东西:

In [3]: numpy.where(multiples, numpy.random.choice([-1, 0, 1], 1), 0)
Out[3]: array([ 0,  0,  0, -1, -1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -1, -1, -1, -1,  0,
                0,  0,  0,  0,  0, -1, -1,  0, -1, -1,  0,  0,  0,  0, -1, -1,  0,
                0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -1, -1,  0,  0,  0,  0,  0,
               -1, -1, -1,  0, -1, -1,  0,  0,  0, -1, -1,  0])

但问题是它只执行一次numpy.random.choice([-1, 0, 1], 1),并保留该结果并在任何地方使用它。我希望它在每次multiples 中的值为True 时运行。

【问题讨论】:

    标签: python arrays python-3.x numpy


    【解决方案1】:
    out = np.random.randint(-1, 2, multiples.shape)
    out[~multiples] = 0
    

    【讨论】:

    • 或使用np.where : np.where(multiples,np.random.randint(-1, 2, multiples.shape),0)
    • 同理,我可以使用np.where(multiples, np.random.choice([-1, 0, 1], multiples.shape, replace=True), 0)。该死的,我怎么一开始就没有想到!?!谢谢@jmhl 和@Divakar。
    【解决方案2】:

    您可以使用np.random.choice 在列表[-1,0,1] 中生成随机数,并将它们放入对应于输入数组中True 位置的输出数组中,就像这样 -

    newvals = [-1,0,1] # Values to be put at places of True in input array
    
    out = np.zeros(multiples.size,dtype=int) # Setup output array
    
    # Finally use np.random.choice to get random numbers from newvals as many
    # as there are True elements in input array and put into the output array 
    # indexed by the corresponding True places in the input array
    out[multiples] = np.random.choice(newvals, multiples.sum(), replace=True)
    

    示例运行 -

    In [44]: multiples
    Out[44]: 
    array([ True,  True, False,  True,  True, False,  True,  True, False,
            True, False,  True, False,  True,  True,  True,  True, False,
            True,  True], dtype=bool)
    
    In [45]: newvals
    Out[45]: [9, 10, 11]
    
    In [46]: out
    Out[46]: 
    array([11, 10,  0,  9,  9,  0, 10, 11,  0, 10,  0, 11,  0,  9, 10, 11,  9,
            0, 10, 10])
    

    【讨论】:

    • 为什么要打扰nonzero
    • @user2357112 因为我需要得到nonzerosidx.size 的计数。我想我可以在那里使用multiples.sum()
    • 您之前使用 idx 和 nonzero 的解决方案对我来说更直观。无论如何,很好的答案,我正在努力解决它。
    • @LuisMiguel 好吧,如果您将multiples 想象为一个布尔数组,multiples.sum() 将指示输入数组中非零的数量,所以是的,需要考虑一下。无论哪个有效:)
    • np.count_nonzerononzero 使用它来预分配其输出数组。
    【解决方案3】:

    你有没有尝试做一个 for 循环?

    for k in range(0,your x size):
        for j in range(0, your y size):
            if array[k][j] == True:
                array[k][j] = (which value you want)
            else:
                array[k][j] = (which value you want)
    

    如果你想记录,定义一个新矩阵为A=np.zeros((xsize,ysize), 'uint8') 然后在第二个for循环中添加A[k][j] = array[k][j]

    显示它print (A) 会帮助你..

    【讨论】:

    • For 循环非常低效。感谢您的回答,但它非常简单且效率低下。请首先阅读更多关于如何避免 Python 中的循环。
    • 但它有效。在设计解决方案中有两条定律。 1-保持简单和愚蠢 2-有不止一种方法可以做到这一点。但是感谢您的低效评论。 @Kartik
    • 我不只是想让它工作。即使理论上有效,但如果超过一定时间,仍然被认为是失败的。我有数十亿条记录要处理,还有最后期限要完成。如果一个模型不起作用,我需要尝试其他模型,记录整个过程,以及介于两者之间的大量其他内容。在项目开始和截止日期之间,我一直在做我需要做的所有事情。处理器速度只能节省那么多时间,因此是优化的原因。我向其报告的人永远不会同意等待循环结束。
    • 区别在于现实世界和初级计算机科学理论。这是一个很大的区别。如果我最初的评论过于苛刻,我很抱歉,但鉴于这种情况,你的回答效率很低。这不是个人评论,我什至不认识你。而且我不是在寻找设计解决方案,显然我可以在没有 SO 帮助的情况下实施。
    • 没关系。我也很抱歉@Kartik。你说得对。
    猜你喜欢
    • 2019-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-29
    • 1970-01-01
    • 1970-01-01
    • 2013-10-22
    • 1970-01-01
    相关资源
    最近更新 更多