Кто-нибудь может предложить более быстрый способ создания этого массива? - PullRequest
1 голос
/ 20 февраля 2020

Я создаю этот массив для своего шейдера, и этот шаг очень медленный, поскольку он составляет вложенное значение для l oop. В настоящее время этот метод занимает около 1 се c, чтобы создать это. Может кто-нибудь предложить более быстрый способ создания этого массива.

import numpy as np

elems = []
b = 23503  
a = 24 



for i in range(0, a - 1):
    for j in range(0, b - 1):
        elems += [j + b * i, j + b * i + 1, j + b * (i + 1)]
        elems += [j + b * (i + 1), j + b * (i + 1) + 1, j + b * i + 1]

elems = np.array(elems, dtype=np.int32)

Ответы [ 2 ]

4 голосов
/ 20 февраля 2020

Сначала я бы признал, что много повторных вычислений. Базовый член, включающий переменные итератора, здесь i*b+j, поэтому давайте NumPy создадим массив, содержащий эти значения в порядке их появления:

ib_j = (np.arange(a-1)[:, None]*b + np.arange(b-1)).flatten()

Далее мы вычисляем шесть различных столбцов из на этой базе сложите их горизонтально и сгладьте:

def create_shader_array(a, b):
    ib_j = (np.arange(a-1)[:, None]*b + np.arange(b-1)).flatten()
    return np.column_stack((ib_j, ib_j+1, ib_j+b, ib_j+b, ib_j+b+1, ib_j+1)).flatten()

Проверка:

>>> all(create_shader_array(a, b) == AKS(a, b)) # AKS is your original implementation
True

Время:

>>> %timeit AKS(24, 23503)
1.02 s ± 8.25 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
>>> %timeit create_shader_array(24, 23503)
28.8 ms ± 364 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
3 голосов
/ 20 февраля 2020

Вы можете использовать meshgrid для покрытия итераций i и j, а затем для внешнего добавления, чтобы получить внутреннюю штриховку. Использование ravel в конце для получения одномерного массива.

inner = np.array([0, 1, b, b, b+1, 1], dtype="int32")
j, i = np.meshgrid(np.arange(b-1), np.arange(a-1))
elems = np.add.outer((j+b*i), inner).ravel()

или с однострочником:

elems = ([0, 1, b, b, b+1, 1]+np.arange(b-1)[:, None]+b*np.arange(a-1)[:,None, None]).ravel()

На моем компьютере <6ms </p>

In [9]: %timeit ([0, 1, b, b, b+1, 1]+np.arange(b-1)[:,None]+b*np.arange(a-1)[:
   ...: ,None, None]).ravel()                                                   
5.23 ms ± 112 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [10]: %timeit create_shader_array(a, b)                                      
29.8 ms ± 176 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
...