Создание векторизованной numpy.meshgrid из 2D-массивов для создания 3D-сеток - PullRequest
1 голос
/ 27 марта 2019

Есть ли способ векторизовать создание np.meshgrid?

#Example of normal np.meshgrid

x = [1.22749725, 2.40009184, 1.48602747, 2.83286752, 2.37426951]
y = [1.23816021, 1.69811451, 2.08692546, 2.13706377, 1.60298873]
gridrez=10

X,Y = np.meshgrid(np.linspace(min(x), max(x), endpoint=True, num=gridrez), 
                  np.linspace(min(y), max(y), endpoint=True, num=gridrez))
# X.shape = 10x10
# Y.shape = 10x10

Я хотел бы повторить эту функцию, но вместо x, где y являются массивами 1x5, они являются массивами 1000x5, и в результате XY будет 1000x10x10.Заметьте, я нашел способ векторизации пространства np.lins, так что не беспокойтесь об этом.Предположим, у нас есть два (1000x10) массива и мы хотим создать сетку размером 1000x10x10.Когда я передаю ответ, я получаю сетку (10000,10000) вместо 1000x10x10

1 Ответ

1 голос
/ 27 марта 2019

Вот один, используя vectorized-linspace : create_ranges -

# https://stackoverflow.com/a/40624614/ @Divakar
def create_ranges(start, stop, N, endpoint=True):
    if endpoint==1:
        divisor = N-1
    else:
        divisor = N
    steps = (1.0/divisor) * (stop - start)
    return steps[:,None]*np.arange(N) + start[:,None]

def linspace_nd(x,y,gridrez):
    a1 = create_ranges(x.min(1), x.max(1), N=gridrez, endpoint=True)
    a2 = create_ranges(y.min(1), y.max(1), N=gridrez, endpoint=True)
    out_shp = a1.shape + (a2.shape[1],)
    Xout = np.broadcast_to(a1[:,None,:], out_shp)
    Yout = np.broadcast_to(a2[:,:,None], out_shp)
    return Xout, Yout

Окончательные выходные значения при linspace_nd будут 3D сеточными представлениями в векторизованные выходные данные linspace и, как таковые, будут эффективными с точки зрения памяти и, следовательно, хорошими с точки зрения производительности.

В качестве альтернативы, если вам нужны выходные данные с собственными областями памяти, а не с представлениями, вы можете использовать np.repeat для репликаций -

Xout = np.repeat(a1[:,None,:],a2.shape[1],axis=1)
Yout = np.repeat(a2[:,:,None],a1.shape[1],axis=2)

Сроки создания такого массива с views -

In [406]: np.random.seed(0)
     ...: x = np.random.rand(1000,5)
     ...: y = np.random.rand(1000,5)

In [408]: %timeit linspace_nd(x,y,gridrez=10)
1000 loops, best of 3: 221 µs per loop
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...