【问题标题】:How to randomly mix N arrays in numpy?如何在numpy中随机混合N个数组?
【发布时间】:2017-12-05 16:52:48
【问题描述】:

我有一个相同形状的 N numpy 数组的列表。我需要通过以下方式将它们组合成一个数组。输出数组的每个元素都应从输入数组之一的相应位置随机取。

例如,如果我需要决定在位置 [2,0,7] 使用什么值,我会在所有 N 个输入数组中获取位于该位置的所有值。所以,我得到 N 个值,然后随机选择一个值。

让它更复杂一点。我想为每个输入数组分配一个概率,以便选择值的概率取决于它是哪个输入数组。

【问题讨论】:

    标签: python arrays numpy random


    【解决方案1】:
    import numpy as np
    import itertools as it
    
    x = np.random.choice(np.arange(10), (2,3,4))  # pass probabilities with p=...
    N = 10
    a = [k*np.ones_like(x) for k in range(N)]  # list of N arrays of same shape
    y = np.empty(a[0].shape)  # output array
    
    # Generate list of all indices of arrays in a (no matter what shape, this is
    # handled with *) and set elements of output array y.
    for index in list(it.product(*list(np.arange(n) for n in x.shape))):
        y[index] = a[x[index]][index]
    # a[x[index]] is the array chosen at a given index.
    # a[x[index]][index] is the element of this array at the given index.
    
    # expected result with the choice of list a: x==y is True for all elements
    

    “更复杂的部分”应该用numpy.random.choice的参数p来处理。其他任何内容都应在 cmets 中进行解释。使用* 这应该适用于a 中任意形状的数组(我希望)。

    【讨论】:

      【解决方案2】:

      让我们只使用 numpy 内置插件来处理这个问题:它会比 for 循环更快。

      import numpy as np
      
      # N = 3 dummy arrays for the example
      a = np.zeros([4, 5])
      b = 10 * np.ones([4, 5])
      c = 2 * b
      
      arr = np.array([a, b, c])  # this is a 3D array containing your N arrays
      N = arr.shape[0]
      
      idx = np.random.choice(range(N), 4 * 5)  # 4 and 5 are the common dimensions of your N arrays
      
      # treating this a a 1D problem, but treating as 2D is possible too.
      arr.reshape(N, 20)[idx.ravel(), np.arange(20)].reshape(4, 5)
      

      如果你想有不同的概率,你可以将参数 p 传递给 np.random.choice (一个形状为 (N,) 的数组,其总和必须为 1):

      idx_p = np.random.choice(range(n_arr), 4 * 5, p = [0.1, 0.2, 0.7])
      arr.reshape(n_arr, 20)[idx_p.ravel(), np.arange(20)].reshape(4, 5)
      

      这给出:

      # first result:
      array([[  0.,   0.,   0.,  20.,  10.],
             [ 20.,   0.,  20.,   0.,  10.],
             [  0.,  10.,   0.,  10.,   0.],
             [ 10.,  20.,  10.,   0.,  10.]])
      # second result with many 20, a few 10 and fewer 0:
      array([[ 10.,   0.,  20.,  20.,  20.],
             [ 20.,   0.,  20.,  20.,  20.],
             [ 10.,  20.,  20.,  20.,  10.],
             [ 20.,  10.,  20.,  20.,  20.]])
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-03
        • 2011-05-21
        • 1970-01-01
        • 2019-04-24
        • 2023-03-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多