Используя два np.linspace, как заполнить 2D-массив сложными значениями? - PullRequest
0 голосов
/ 30 сентября 2018

Я пытаюсь заполнить 2D-массив complex(x,y), где x и y из двух двух массивов:

xstep = np.linspace(xmin, xmax, Nx)
ystep = np.linspace(ymin, ymax, Ny)

Однако я не могу понять, как "распределить эти значения по двумерному массиву.

Пока что мои попытки на самом деле не работают.Я надеялся на что-то вроде:

result = np.array(xstep + (1j * ystep))

Может быть, что-то из fromfunction, meshgrid или full, но я не могу заставить его работать.

Например, скажите, что я делаю это:

xstep = np.linspace(0, 1, 2)  # array([0., 1.])
ystep = np.linspace(0, 1, 3)  # array([0. , 0.5, 1. ])

Я пытаюсь построить ответ:

array([
[0+0j, 0+0.5j, 0+1j],
[1+0j, 1+0.5j, 1+1j]
])

Обратите внимание, что я не женат на linspace, поэтому любойболее быстрый метод также подойдет, это просто моя естественная отправная точка для создания этого массива, новичок в Numpy.

Ответы [ 3 ]

0 голосов
/ 30 сентября 2018
In [4]: xstep = np.linspace(0, 1, 2)

In [5]: ystep = np.linspace(0, 1, 3)

In [6]: xstep[:, None] + 1j*ystep
Out[6]: 
array([[0.+0.j , 0.+0.5j, 0.+1.j ],
       [1.+0.j , 1.+0.5j, 1.+1.j ]])

xstep[:, None] эквивалентно xstep[:, np.newaxis], и его целью является добавление новой оси к xstep справа .Таким образом, xstep[:, None] является двумерным массивом формы (2, 1).

In [19]: xstep[:, None].shape
Out[19]: (2, 1)

xstep[:, None] + 1j*ystep, таким образом, является суммой двумерного массива формы (2, 1) и одномерного массива формы (3,).

Вещание NumPy разрешает этот очевидный конфликт формы, автоматически добавляя новые оси (длиной 1) слева .Так, по правилам вещания NumPy, 1j*ystep повышается до массива (1, 3).(Обратите внимание, что xstep[:, None] требуется для явного добавления новых осей справа, но широковещание автоматически добавит оси слева. Вот почему 1j*ystep[None, :] было ненужным, хотя и действительным.)

Широковещание дополнительно расширяет оба массива.в общую форму (2, 3) (но с эффективным использованием памяти, без копирования данных).Значения по осям длины 1 передаются повторно:

In [15]: X, Y = np.broadcast_arrays(xstep[:, None], 1j*ystep)

In [16]: X
Out[16]: 
array([[0., 0., 0.],
       [1., 1., 1.]])

In [17]: Y
Out[17]: 
array([[0.+0.j , 0.+0.5j, 0.+1.j ],
       [0.+0.j , 0.+0.5j, 0.+1.j ]])
0 голосов
/ 30 сентября 2018

Вы можете использовать np.ogrid с мнимым «шагом» для получения семантики linspace:

y, x = np.ogrid[0:1:2j, 0:1:3j]                                                                               
y + 1j*x
# array([[0.+0.j , 0.+0.5j, 0.+1.j ],                                                                                 
#        [1.+0.j , 1.+0.5j, 1.+1.j ]])                                                                                

Здесь линия ogrid означает создание открытой 2D-сетки.ось от 0: 0 до 1, 2 шага, ось от 1: 0 до 1, 3 шага.Тип фрагмента «step» действует как переключатель, если он является мнимым (на самом деле что-либо сложного типа), его абсолютное значение берется, а выражение обрабатывается как linspace.В противном случае применяется семантика диапазона.

Возвращаемые значения

y, x
# (array([[0.],                                                                                                       
#         [1.]]), array([[0. , 0.5, 1. ]]))                                                                                                                                                                                          

"готовы к трансляции", поэтому в примере мы можем просто добавить их и получить полную 2D-сетку.

Если мы позволим себе воображаемый параметр «stop» во втором срезе (который работает только с семантикой linspace, поэтому в зависимости от вашего стиля вы можете предпочесть его избегать), он может быть сжат до одной строки:

sum(np.ogrid[0:1:2j, 0:1j:3j])
# array([[0.+0.j , 0.+0.5j, 0.+1.j ],
#        [1.+0.j , 1.+0.5j, 1.+1.j ]])

Аналогичным, но потенциально более производительным методом будет предварительное распределение, а затем трансляция:

out = np.empty((y.size, x.size), complex)
out.real[...], out.imag[...] = y, x
out
# array([[0.+0.j , 0.+0.5j, 0.+1.j ],
#        [1.+0.j , 1.+0.5j, 1.+1.j ]])

И еще один, использующий внешнюю сумму:

np.add.outer(np.linspace(0,1,2), np.linspace(0,1j,3))
# array([[0.+0.j , 0.+0.5j, 0.+1.j ],
#        [1.+0.j , 1.+0.5j, 1.+1.j ]])
0 голосов
/ 30 сентября 2018

Используйте reshape(-1,1) для xstep как:

xstep = np.linspace(0, 1, 2)  # array([0., 1.])
ystep = np.linspace(0, 1, 3)  # array([0. , 0.5, 1. ])

result = np.array(xstep.reshape(-1,1) + (1j * ystep))

result

array([[0.+0.j , 0.+0.5j, 0.+1.j ],
       [1.+0.j , 1.+0.5j, 1.+1.j ]])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...