简体   繁体   English

创建一个数组,其中每个元素存储其索引

[英]Create an array where each element stores its indices

I want to create a 2d numpy array where every element is a tuple of its indices. 我想创建一个2d numpy数组,其中每个元素都是其索引的元组。

Example (4x5): 示例(4x5):

array([[[0, 0],
        [0, 1],
        [0, 2],
        [0, 3],
        [0, 4]],

       [[1, 0],
        [1, 1],
        [1, 2],
        [1, 3],
        [1, 4]],

       [[2, 0],
        [2, 1],
        [2, 2],
        [2, 3],
        [2, 4]],

       [[3, 0],
        [3, 1],
        [3, 2],
        [3, 3],
        [3, 4]]])

I would create an python list with the following list comprehension: 我将使用以下列表理解创建一个python list

[[(y,x) for x in range(width)] for y in range(height)]

Is there a faster way to achieve the same, maybe with numpy methods? 有没有更快的方法来实现相同的,也许有numpy方法?

Do you do this because you need it or just for sport? 你这样做是因为你需要它还是只是为了运动? In the former case: 在前一种情况下:

np.moveaxis(np.indices((4,5)), 0, -1)

np.indices does precisely what its name suggests. np.indices正是它的名字所暗示的。 Only it arranges axes differently to you. 只有它以不同的方式排列轴。 So we move them with moveaxis 所以我们用moveaxis移动它们

As @Eric points out one attractive feature of this method is that it works unmodified at arbitrary number of dimensions: 正如@Eric所指出的,这种方法的一个吸引人的特点是它可以在任意数量的维度上进行修改:

dims = tuple(np.multiply.reduceat(np.zeros(16,int)+2, np.r_[0, np.sort(np.random.choice(16, np.random.randint(10)))]))
# len(dims) == ?
np.moveaxis(np.indices(dims), 0, -1) # works

Here's an initialization based method - 这是一个基于初始化的方法 -

def create_grid(m,n):
    out = np.empty((m,n,2),dtype=int) #Improvement suggested by @AndrasDeak
    out[...,0] = np.arange(m)[:,None]
    out[...,1] = np.arange(n)
    return out

Sample run - 样品运行 -

In [47]: create_grid(4,5)
Out[47]: 
array([[[0, 0],
        [0, 1],
        [0, 2],
        [0, 3],
        [0, 4]],

       [[1, 0],
        [1, 1],
        [1, 2],
        [1, 3],
        [1, 4]],

       [[2, 0],
        [2, 1],
        [2, 2],
        [2, 3],
        [2, 4]],

       [[3, 0],
        [3, 1],
        [3, 2],
        [3, 3],
        [3, 4]]])

Runtime test for all approaches posted thus far on (4,5) grided and bigger sizes - 到目前为止发布的所有方法的运行时测试(4,5)格栅和更大的尺寸 -

In [111]: %timeit np.moveaxis(np.indices((4,5)), 0, -1)
     ...: %timeit np.mgrid[:4, :5].swapaxes(2, 0).swapaxes(0, 1)
     ...: %timeit np.mgrid[:4,:5].transpose(1,2,0)
     ...: %timeit create_grid(4,5)
     ...: 
100000 loops, best of 3: 11.1 µs per loop
100000 loops, best of 3: 17.1 µs per loop
100000 loops, best of 3: 17 µs per loop
100000 loops, best of 3: 2.51 µs per loop

In [113]: %timeit np.moveaxis(np.indices((400,500)), 0, -1)
     ...: %timeit np.mgrid[:400, :500].swapaxes(2, 0).swapaxes(0, 1)
     ...: %timeit np.mgrid[:400,:500].transpose(1,2,0)
     ...: %timeit create_grid(400,500)
     ...: 
1000 loops, best of 3: 351 µs per loop
1000 loops, best of 3: 1.01 ms per loop
1000 loops, best of 3: 1.03 ms per loop
10000 loops, best of 3: 190 µs per loop

You can abuse numpy.mgrid or meshgrid for this purpose: 您可以为此目的滥用numpy.mgridmeshgrid

>>> import numpy as np
>>> np.mgrid[:4,:5].transpose(1,2,0)
array([[[0, 0],
        [0, 1],
        [0, 2],
        [0, 3],
        [0, 4]],

       [[1, 0],
        [1, 1],
        [1, 2],
        [1, 3],
        [1, 4]],

       [[2, 0],
        [2, 1],
        [2, 2],
        [2, 3],
        [2, 4]],

       [[3, 0],
        [3, 1],
        [3, 2],
        [3, 3],
        [3, 4]]])

You can use numpy.mgrid and swap it's axes: 你可以使用numpy.mgrid并交换它的轴:

>>> # assuming a 3x3 array
>>> np.mgrid[:3, :3].swapaxes(-1, 0)
array([[[0, 0],
        [1, 0],
        [2, 0]],

       [[0, 1],
        [1, 1],
        [2, 1]],

       [[0, 2],
        [1, 2],
        [2, 2]]])

That still differs a bit from your desired array so you can roll your axes: 这仍然与您想要的数组略有不同,因此您可以滚动轴:

>>> np.mgrid[:3, :3].swapaxes(2, 0).swapaxes(0, 1)
array([[[0, 0],
        [0, 1],
        [0, 2]],

       [[1, 0],
        [1, 1],
        [1, 2]],

       [[2, 0],
        [2, 1],
        [2, 2]]])

Given that someone timed the results I also want to present a manual based version that "beats 'em all": 鉴于有人对结果进行了计时,我还想提出一个手动的基于的版本,“打败所有人”:

import numba as nb
import numpy as np

@nb.njit
def _indexarr(a, b, out):
    for i in range(a):
        for j in range(b):
            out[i, j, 0] = i
            out[i, j, 1] = j
    return out

def indexarr(a, b):
    arr = np.empty([a, b, 2], dtype=int)
    return _indexarr(a, b, arr)

Timed: 定时:

a, b = 400, 500
indexarr(a, b)  # numba needs a warmup run
%timeit indexarr(a, b)                                  # 1000 loops, best of 3: 1.5 ms per loop
%timeit np.mgrid[:a, :b].swapaxes(2, 0).swapaxes(0, 1)  # 100 loops, best of 3: 7.17 ms per loop
%timeit np.mgrid[:a, :b].transpose(1,2,0)               # 100 loops, best of 3: 7.47 ms per loop
%timeit create_grid(a, b)                               # 100 loops, best of 3: 2.26 ms per loop

and on a smaller array: 并在一个较小的阵列上:

a, b = 4, 5
indexarr(a, b)
%timeit indexarr(a, b)                                 # 100000 loops, best of 3: 13 µs per loop
%timeit np.mgrid[:a, :b].swapaxes(2, 0).swapaxes(0, 1) # 10000 loops, best of 3: 181 µs per loop
%timeit np.mgrid[:a, :b].transpose(1,2,0)              # 10000 loops, best of 3: 182 µs per loop
%timeit create_grid(a, b)                              # 10000 loops, best of 3: 32.3 µs per loop

As promised it "beats 'em all" in terms of performance :-) 正如所承诺的那样,它在性能方面“击败了所有人”:-)

暂无
暂无

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

相关问题 如何创建一个二维numpy数组,每个元素都是其索引的元组? - How to make a 2D numpy array with each element being a tuple of its indices? 使用NumPy从另一个数组及其索引创建一个2D数组 - Create a 2D array from another array and its indices with NumPy 查找索引,其中一个数组大于第二个数组中的元素 - find indices where one array is larger than an element in a second array 如何创建一个 boolean 数组,其中值基于索引数组? - How to create a boolean array where the value is based on an array of indices? 根据其元素拆分 Numpy 数组,其中数组的每个元素都是唯一的 - Splitting Numpy arrays based on its elements, where each element of the array is unique 用各自索引的元组替换多维数组的每个元素 - Replace each element of multidimensional array with tuple of respective indices Append 元素到每个元素的索引 - Append indices of element to each element 如何在numpy中创建数组元组的3D数组,其中3D数组的每个元素就像np.where的输出? - How to create a 3D array of a tuple of arrays in numpy, where each element of the 3D array is like the output of np.where? Numpy:从一维整数数组创建新数组,其中整数数组中的每个元素表示新数组中的元素数 - Numpy: Create new array from 1d integer array where each element in integer array represents the number of elements in the new array 获取numpy 1d数组的索引,其中value大于前一个元素 - Get indices of numpy 1d array where value is greater than previous element
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM