Итак, продолжая обсуждение @TheBlackCat и я имели в this answer, я хотел бы знать, как лучше всего передать аргументы в векторную функцию Numpy. Функция вопроса определяется следующим образом:Лучший способ передать повторяющийся параметр в векторизованную функцию Numpy
vect_dist_funct = np.vectorize(lambda p1, p2: vincenty(p1, p2).meters)
где vincenty
происходит от Geopy package.
я в настоящее время называю vect_dist_funct
таким образом:
def pointer(point, centroid, tree_idx):
intersect = list(tree_idx.intersection(point))
if len(intersect) > 0:
points = pd.Series([point]*len(intersect)).values
polygons = centroid.loc[intersect].values
dist = vect_dist_funct(points, polygons)
return pd.Series(dist, index=intercept, name='Dist').sort_values()
else:
return pd.Series(np.nan, index=[0], name='Dist')
points['geometry'].apply(lambda x: pointer(point=x.coords[0], centroid=line['centroid'], tree_idx=tree_idx))
(Пожалуйста, обратитесь к вопросу здесь: Labelled datatypes Python)
Моего вопроса относится к тому, что происходит внутри функций pointer
. Причина, по которой я конвертирую points
в pandas.Series
, а затем получать значения (в 4-й строке, как раз под оператором if
), сделать ее в том же виде, что и полигоны. Если я просто назову точки либо points = [point]*len(intersect)
, либо как points = itertools.repeat(point, len(intersect))
, Numpy жалуется, что он «не может передавать массивы размера (n, 2) и размера (n,) вместе» (n - длина intersect
).
Если я звоню vect_dist_funct
так: dist = vect_dist_funct(itertools.repeat(points, len(intersect)), polygons)
, vincenty
жалуется, что я передал ему слишком много аргументов. Я полностью потеряю, чтобы понять разницу между ними.
Обратите внимание, что это координаты, поэтому они всегда будут попарно. Вот примеры того, как point
и polygons
выглядеть:
point = (-104.950752 39.854744) # Passed directly to the function like this.
polygons = array([(-104.21750802451864, 37.84052458697633),
(-105.01017084789603, 39.82012158954065),
(-105.03965315742742, 40.669867471420886),
(-104.90353460825702, 39.837631505433706),
(-104.8650601872832, 39.870796282334744)], dtype=object)
# As returned by statement centroid.loc[intersect].values
Что такое лучший способ вызвать vect_dist_funct
в этом обстоятельстве, так что я могу иметь векторизованный вызов, и оба Numpy и vincenty не будут жаловаться, что я прохождение неправильных аргументов? Также требуются методы, которые приводят к минимальному потреблению памяти и увеличению скорости. Цель состоит в том, чтобы вычислить расстояние между точкой до каждого центроида многоугольника.
После беглого взгляда я нахожу ваш вопрос неясен. В любом случае, поскольку «* не может передавать массивы размера (n, 2) и размер (n,) вместе *»: вы можете передавать только «(n, 2)» с помощью формы '(n, 1)', так что у вас есть чтобы ввести конечный синглтон с '[:, None]' в ваш 1d-массив, чтобы сделать что-то вроде этой работы. –
Также обратите внимание на такие вещи, как '[point] * len (intersect)': вы можете получить список, содержащий * ссылку на ту же переменную *. Если позже вы измените этот список, вы можете ошибочно перепутать все элементы списка сразу. Обычно безопаснее делать что-то вроде '[p для _ в диапазоне (len (intersect))]'. –
@ AndrasDeak, какая часть вопроса непонятна? Я отредактирую его соответствующим образом. В основном то, что я пытаюсь сделать, - это вычислить расстояния между одной точкой и набором точек наиболее эффективным образом. Я думал, что новинка Numpy ускорит все для меня. – Kartik