简体   繁体   English

如何在numpy中创建一个增加的多维数组

[英]How to create an increasing, multi-dimensional array in numpy

I am trying to perform inverse warping given a homography matrix, and to do that efficiently I need a numpy array that looks like this: 我试图在给出单应矩阵的情况下执行逆变形,为了有效地做到这一点,我需要一个看起来像这样的numpy数组:

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

Where n is an image's width ( im.shape[0] ) and p is the image's height ( im.shape[1] ). 其中n是图像的宽度( im.shape[0] ),p是图像的高度( im.shape[1] )。 Any idea on how to efficiently construct numpy arrays that look like that? 关于如何有效地构建看起来那样的numpy数组的任何想法?

Edit: 编辑:

There is some discussion on which is the fastest, if anyone has any info on that I think it'd be interesting to hear. 有一些讨论哪个是最快的,如果有人有任何信息,我认为听起来很有趣。 I appreciate everyone's help! 我感谢大家的帮助!

Using indices_merged_arr_generic_using_cp by @unutbu - 使用indices_merged_arr_generic_using_cp的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)

Sample run - 样品运行 -

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]])

Benchmarking 标杆

Other approaches - 其他方法 -

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

Timings - 计时 -

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

You could use np.mgrid to create the grid (first two entries of each subarray) with np.stack to concatenate them: 你可以使用np.mgrid创建网格(每个子np.stack前两个条目)和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]])

In this case I used 3 as width and height but by altering the arguments for np.mgrid you can change them. 在这种情况下,我使用3作为宽度和高度,但通过更改np.mgrid的参数,您可以更改它们。

In one line: 在一行中:

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

Basically, key to getting indices like this is using something like indices , mgrid / meshgrid or the like. 基本上,获得像这样的索引的关键是使用像indicesmgrid / meshgrid之类的东西。

You can do this all without looping using numpy.tile and numpy.repeat and a pre-allocated container 你可以在不使用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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM