Численные точки сетки

Я хочу создать список точек, которые будут соответствовать сетке. Поэтому, если я хочу создать сетку области от (0,0) до (1,1), она будет содержать точки (0,0), (0,1), (1,0), (1, 0).

Я знаю, что это можно сделать с помощью следующего кода:

g = np.meshgrid([0,1],[0,1])
np.append(g[0].reshape(-1,1),g[1].reshape(-1,1),axis=1)

Удовлетворение результата:

array([[0, 0],
       [1, 0],
       [0, 1],
       [1, 1]])

Мой вопрос двоякий:

  • Есть ли лучший способ сделать это?
  • Есть ли способ обобщить это на более высокие измерения?

Ответ 1

Я только заметил, что документация в numpy обеспечивает еще более быстрый способ сделать это:

X, Y = np.mgrid[xmin:xmax:100j, ymin:ymax:100j]
positions = np.vstack([X.ravel(), Y.ravel()])

Это можно легко обобщить на большее количество измерений с помощью связанной функции meshgrid2 и отображения "ravel" в результирующую сетку.

g = meshgrid2(x, y, z)
positions = np.vstack(map(np.ravel, g))

Результат примерно в 35 раз быстрее, чем метод zip для трехмерного массива с 1000 тиков на каждой оси.

Источник: http://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.gaussian_kde.html#scipy.stats.gaussian_kde

Чтобы сравнить два метода, рассмотрим следующие разделы кода:

Создайте пометные метки, которые помогут создать сетку.

In [23]: import numpy as np

In [34]: from numpy import asarray

In [35]: x = np.random.rand(100,1)

In [36]: y = np.random.rand(100,1)

In [37]: z = np.random.rand(100,1)

Определите функцию, с которой соединен mgilson для meshgrid:

In [38]: def meshgrid2(*arrs):
   ....:     arrs = tuple(reversed(arrs))
   ....:     lens = map(len, arrs)
   ....:     dim = len(arrs)
   ....:     sz = 1
   ....:     for s in lens:
   ....:        sz *= s
   ....:     ans = []
   ....:     for i, arr in enumerate(arrs):
   ....:         slc = [1]*dim
   ....:         slc[i] = lens[i]
   ....:         arr2 = asarray(arr).reshape(slc)
   ....:         for j, sz in enumerate(lens):
   ....:             if j != i:
   ....:                 arr2 = arr2.repeat(sz, axis=j)
   ....:         ans.append(arr2)
   ....:     return tuple(ans)

Создайте сетку и время для двух функций.

In [39]: g = meshgrid2(x, y, z)

In [40]: %timeit pos = np.vstack(map(np.ravel, g)).T
100 loops, best of 3: 7.26 ms per loop

In [41]: %timeit zip(*(x.flat for x in g))
1 loops, best of 3: 264 ms per loop

Ответ 2

Являются ли ваши координатные точки постоянными? Если это так, вы можете использовать numpy.ndindex

print list(np.ndindex(2,2))

Более высокие размеры:

print list(np.ndindex(2,2,2))

К сожалению, это не соответствует требованиям ОП, поскольку интегральное предположение (начиная с 0) не выполняется. Я оставлю этот ответ только в том случае, если кто-то ищет то же самое, где эти предположения верны.


Другой способ сделать это зависит от zip:

g = np.meshgrid([0,1],[0,1])
zip(*(x.flat for x in g))

Эта часть хорошо масштабируется до произвольных размеров. К сожалению, np.meshgrid не очень хорошо масштабируется для нескольких измерений, поэтому часть должна быть разработана или (если она работает), вы можете использовать этот SO ответ для создания вашей собственной функции ndmeshgrid.

Ответ 3

Еще один способ сделать это:

np.indices((2,2)).T.reshape(-1,2)

Что можно обобщить на более высокие размеры, например:

In [60]: np.indices((2,2,2)).T.reshape(-1,3)
Out[60]:
array([[0, 0, 0],
       [1, 0, 0],
       [0, 1, 0],
       [1, 1, 0],
       [0, 0, 1],
       [1, 0, 1],
       [0, 1, 1],
       [1, 1, 1]])