Numpy вещание на нескольких массивах - PullRequest
0 голосов
/ 17 сентября 2018

У меня есть база для плоскости в 3 измерениях: (u, v).

Я хотел бы получить все линейные комбинации этого базиса, чтобы в основном пройти всю мою плоскость:

для i в [0, 512 [и j в [0, 512 [, получить все (i * u + j * v).

) Мне нужно, чтобы это было быстро, так что циклы на самом деле не вариант,Как я могу сделать это с бесшумной трансляцией?

Я посмотрел на https://docs.scipy.org/doc/numpy-1.13.0/user/basics.broadcasting.html, и у меня сложилось впечатление, что это невозможно сделать ...

Пробовал:

# This is an orthonormal basis but there is no guarantee it is
u = np.array([1, 0, 0])
v = np.array([0, 1, 0])
tmp = np.arange(512)
factors = itertools.combinations(tmp, 2)
pixels = factors[0] * u + factors[1] + v

Но, очевидно, это не работает.

Есть ли решение этой проблемы?И если да, то как?

Ответы [ 2 ]

0 голосов
/ 17 сентября 2018

Несколько изменений в вашем коде

factors = itertools.product(tmp, tmp)
factors = list(zip(*factors))
factors = np.array(factors)
pixels = factors[0][:, None] * u + factors[1][:, None] + v

Во-первых, математическая ошибка: вы хотите декартово произведение , а не комбинации.

Теперь, фактическая синтаксическая ошибка: itertools создает список [(i1, j1), (i2, j2)..], а не массив numpy.Таким образом, чтобы ваша последняя строка работала, вам нужно

  1. zip(*), чтобы преобразовать список в (i1, i2), (j1, j2) формат
  2. , сделать его массивом NumPy
  3. вfactors[0], factors[1] векторов 1D , добавьте [:, None] для преобразования в столбцы, чтобы вещание работало.
0 голосов
/ 17 сентября 2018

Умножить (u, v) на двумерную индексную сетку:

ind = np.indices((512, 512))
pixels = ind[0, ..., np.newaxis] * u + ind[1, ..., np.newaxis] * v

>>> %timeit ind = np.indices((512, 512)); pixels = ind[0, ..., np.newaxis] * u + ind[1, ..., np.newaxis] * v
8.06 ms ± 69.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

Умножить u на одномерный индексный диапазон, умножить v на одномерный индексный диапазон, передать и объединить в 2D:

i512 = np.arange(512)[:, np.newaxis]
pixels = (i512 * u)[:, np.newaxis, :] + (i512 * v)[np.newaxis, :, :]

>>> %timeit i512 = np.arange(512)[:, np.newaxis]; pixels = (i512 * u)[:, np.newaxis, :] + (i512 * v)[np.newaxis, :, :]
4.06 ms ± 58.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...