【问题标题】:How to create an increasing, multi-dimensional array in numpy如何在 numpy 中创建一个递增的多维数组
【发布时间】:2017-09-28 13:44:20
【问题描述】:

我正在尝试在给定单应矩阵的情况下执行反向扭曲,为了有效地做到这一点,我需要一个如下所示的 numpy 数组:

([[0, 0, 1], [0, 1, 1], [0, 2, 1], ... [1, 0, 1], [1, 1, 1], ... [n, p, 1]])

其中 n 是图像的宽度 (im.shape[0]),p 是图像的高度 (im.shape[1])。关于如何有效地构造看起来像这样的 numpy 数组的任何想法?

编辑:

有一些关于哪个最快的讨论,如果有人有任何关于这方面的信息,我想听听会很有趣。感谢大家的帮助!

【问题讨论】:

标签: python arrays opencv numpy


【解决方案1】:

@unutbu 使用indices_merged_arr_generic_using_cp -

def indices_one_grid(n,p):
    ar = np.ones((n,p),dtype=int)
    return indices_merged_arr_generic_using_cp(ar)

示例运行 -

In [141]: indices_one_grid(n=3,p=4)
Out[141]: 
array([[0, 0, 1],
       [0, 1, 1],
       [0, 2, 1],
       [0, 3, 1],
       [1, 0, 1],
       [1, 1, 1],
       [1, 2, 1],
       [1, 3, 1],
       [2, 0, 1],
       [2, 1, 1],
       [2, 2, 1],
       [2, 3, 1]])

基准测试

其他方法 -

def MSeifert(n,p):
    x, y = np.mgrid[:n, :p]
    return np.stack([x.ravel(), y.ravel(), np.ones(x.size, dtype=int)], axis=1)

def DanielF(n,p):
    return np.vstack([np.indices((n,p)), np.ones((1, n,p))]).reshape(3,-1).T

def Aaron(n,p):
    arr = np.empty([n*p,3])
    arr[:,0] = np.repeat(np.arange(n),p)
    arr[:,1] = np.tile(np.arange(p),n)
    arr[:,2] = 1
    return arr

时间安排 -

In [152]: n=1000;p=1000

In [153]: %timeit MSeifert(n,p)
     ...: %timeit DanielF(n,p)
     ...: %timeit Aaron(n,p)
     ...: %timeit indices_one_grid(n,p)
     ...: 
100 loops, best of 3: 15.8 ms per loop
100 loops, best of 3: 8.46 ms per loop
100 loops, best of 3: 10.4 ms per loop
100 loops, best of 3: 4.78 ms per loop

【讨论】:

  • 很棒的基准测试。感谢您如此深入的回复!
【解决方案2】:

您可以使用np.mgrid 创建网格(每个子数组的前两个条目),并使用np.stack 将它们连接起来:

>>> x, y = np.mgrid[:3, :3]   # assuming a 3x3 image
>>> np.stack([x.ravel(), y.ravel(), np.ones(x.size, dtype=int)], axis=1)
array([[0, 0, 1],
       [0, 1, 1],
       [0, 2, 1],
       [1, 0, 1],
       [1, 1, 1],
       [1, 2, 1],
       [2, 0, 1],
       [2, 1, 1],
       [2, 2, 1]])

在这种情况下,我使用 3 作为宽度和高度,但通过更改 np.mgrid 的参数,您可以更改它们。

【讨论】:

    【解决方案3】:

    一行:

    np.vstack([np.indices(im.shape), np.ones((1, *im.shape))]).reshape(3,-1).T
    

    基本上,获得这样的索引的关键是使用 indicesmgrid/meshgrid 或类似的东西。

    【讨论】:

    • 我认为你有一个错字。 *
    • @johnktejik 不,这是解包元组
    【解决方案4】:

    您无需循环使用numpy.tilenumpy.repeat 以及预分配的容器即可完成所有操作

    import numpy as np
    arr = np.empty([n*p,3])
    arr[:,0] = np.repeat(np.arange(n),p)
    arr[:,1] = np.tile(np.arange(p),n)
    arr[:,2] = 1
    

    【讨论】:

    • 我总是忘记 2D 是更简单快捷的方法。
    • @MSeifert 有时可能很慢的是 np.stack 产生的内存分配......但索引比重复和平铺更快可能是真的。
    • @Aaron 这是相同的内存分配只是不同的顺序。我先创建小数组,然后使用堆栈创建大数组。当您先创建大数组,然后创建复制到大数组中的小数组时。
    猜你喜欢
    • 2019-06-09
    • 2018-11-30
    • 1970-01-01
    • 1970-01-01
    • 2010-11-27
    • 1970-01-01
    • 2017-05-02
    • 2016-12-11
    • 2011-11-13
    相关资源
    最近更新 更多