Увеличьте столбцы numpy 2D-массива

У меня есть пример игрушки, в которой используется numpy и внешний пакет PyProj. Lat и lon - это двумерные массивы, которые содержат координаты некоторой информации, относящейся к предметной области. Что я хочу сделать, так это вычислить расстояние на сфере от центральной точки, которую я выбираю произвольно. Форма lat_0 и lon_0 такая:

(2000,1)

Но вызов API inv этого не устраивает. У меня ошибка времени выполнения -

 RuntimeError: Buffer lengths not the same

Он хочет массив формы

(2000,50). 

Поэтому я хочу, чтобы lat_0 и lon_0 имели ту же форму, что и lon и lat, со всеми постоянными значениями, которые являются центральной широтой и долготой. Каков наиболее эффективный способ увеличить столбцы lon_0 и lat_0 и заполнить его центральным значением, чтобы оно имело ту же форму, что и lon и lat, без использования циклов for?

import numpy as np
from pyproj import Geod

lat = np.empty((2000,50))
lat.fill(1)
lon = np.empty((2000,50))
lon.fill(1)


center = int(np.floor(len(lon[-1]) / 2.))
lon_0 = lon[:,center][...,np.newaxis]
lat_0 = lat[:,center][...,np.newaxis]


g = Geod(ellps='WGS84')

distance = g.inv(lon,lat,lon_0,lat_0,radians=True)

person gansub    schedule 11.04.2018    source источник


Ответы (2)


Вероятно, наиболее эффективным способом будет np.broadcast_arrays. Это создает представления меньших массивов без увеличения буфера данных. Общий пример:

    >>> A = np.arange(10).reshape(2, 5)
>>> A
array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]])
>>> B = np.c_[:2]
>>> B
array([[0],
       [1]])
>>> C = np.arange(5)
>>> D = 7

>>> np.broadcast_arrays(A, B)
[array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]]), array([[0, 0, 0, 0, 0],
       [1, 1, 1, 1, 1]])]
>>> np.broadcast_arrays(A, C)
[array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]]), array([[0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4]])]
>>> np.broadcast_arrays(A, D)
[array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]]), array([[7, 7, 7, 7, 7],
       [7, 7, 7, 7, 7]])]

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

>>> AA, BB = np.broadcast_arrays(A, B)
>>> BB
array([[0, 0, 0, 0, 0],
       [1, 1, 1, 1, 1]])
>>> BB[0,0] = 3
>>> BB
array([[3, 3, 3, 3, 3],
       [1, 1, 1, 1, 1]])
>>> B
array([[3],
       [1]])
person Paul Panzer    schedule 11.04.2018
comment
ваш, возможно, более эффективный ответ, но я новичок в numpy broadcast_arrays. Не могли бы вы подсказать, как соотносятся ваши A, B и мои lon, lat, lon_0 и lat_0, чтобы я мог придумать игрушечный пример? - person gansub; 11.04.2018
comment
@gansub Форма B - (2, 1), так что это будет соответствовать вашему lat_0, lon_0; форма A - (2, 5), что соответствует вашим lat и lon. Если вы хотите глубоко понять broadcast_arrays, посмотрите, например, BB.strides. - person Paul Panzer; 11.04.2018

Не уверен на 100%, что понял, что вам нужно, мое предложение кажется неудовлетворительным, но чтобы скопировать массив несколько раз вдоль указанной оси, вы можете использовать numpy repeat

Итак, в вашем случае вы могли бы сделать

lon_0 = np.repeat(lon_0, 50, axis=1)
person Christian    schedule 11.04.2018