【问题标题】:bootstrap numpy 2D array引导 numpy 二维数组
【发布时间】:2019-05-22 20:22:11
【问题描述】:

我正在尝试对形状为 (4,2) 的 base 2D numpy 数组进行替换采样,例如 10 次。最终输出应该是一个 3D numpy 数组。

已经尝试了下面的代码,它可以工作。但是有没有办法在没有 for 循环的情况下做到这一点?

base=np.array([[20,30],[50,60],[70,80],[10,30]])
print(np.shape(base))
nsample=10
tmp=np.zeros((np.shape(base)[0],np.shape(base)[1],10))
for i in range(nsample):
    id_pick = np.random.choice(np.shape(base)[0], size=(np.shape(base)[0]))
    print(id_pick)
    boot1=base[id_pick,:]
    tmp[:,:,i]=boot1
print(tmp)

【问题讨论】:

    标签: python numpy vectorization


    【解决方案1】:

    这是一种矢量化方法 -

    m,n = base.shape
    idx = np.random.randint(0,m,(m,nsample))
    out = base[idx].swapaxes(1,2)
    

    基本思想是我们生成所有可能的索引,np.random.randintidx。那将是一个形状数组(m,nsample)。我们使用这个数组沿第一个轴索引输入数组。因此,它从base 中选择随机行。为了得到形状为(m,n,nsample) 的最终输出,我们需要交换最后两个轴。

    【讨论】:

    • hm.. 这看起来应该可以工作.. 我的 numpy 已经过时了... 看起来 np.take_along_axis 很新。
    • @user3491987 经过进一步检查,发现您正在从输入中选择行。所以,需要很少的改变。请查看对这些的修改。
    【解决方案2】:

    您可以使用 numpy 中的 stack 函数。您的代码将如下所示:

    base=np.array([[20,30],[50,60],[70,80],[10,30]])
    print(np.shape(base))
    nsample=10
    tmp = []
    for i in range(nsample):
        id_pick = np.random.choice(np.shape(base)[0], size=(np.shape(base)[0]))
        print(id_pick)
        boot1=base[id_pick,:]
        tmp.append(boot1)
    tmp = np.stack(tmp, axis=-1)
    print(tmp)
    

    【讨论】:

      【解决方案3】:

      根据@Divakar 的回答,如果您已经知道这个二维数组的形状,则可以在引导时将其视为 (8,) 一维数组,然后对其进行整形:

          m, n = base.shape
          flatbase = np.reshape(base, (m*n,))
          idxs = np.random.choice(range(8), (numReps, m*n))
          bootflats = flatbase[idx]
          boots = np.reshape(flatbase, (numReps, m, n))
      

      【讨论】:

        猜你喜欢
        • 2011-07-07
        • 2020-07-30
        • 2012-04-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-16
        • 2015-09-21
        • 2019-07-28
        相关资源
        最近更新 更多