首页 > 解决方案 > 函数认为我传入一个浮点数

问题描述

我想计算两个数组中所有坐标对之间的距离。这是我写的一些代码:

def haversine(x,y):
    """
    Calculate the great circle distance between two points 
    on the earth (specified in decimal degrees)
    """
    # convert decimal degrees to radians 
    print(type(x))
    lat1, lon1 = np.radians(x)
    lat2, lon2 = np.radians(y)

    # haversine formula 
    dlon = lon2 - lon1 
    dlat = lat2 - lat1 
    a = np.sin(dlat/2)**2 + np.cos(lat1) * np.cos(lat2) * np.sin(dlon/2)**2
    c = 2 * np.arcsin(np.sqrt(a)) 
    r = 6371 # Radius of earth in kilometers. Use 3956 for miles
    return c * r

haversine = np.vectorize(haversine)

数组是gas_coordspostal_coords。注意

type(postal_coords)
>>>numpy.ndarray

type(gas_coords)
>>>numpy.ndarray

并且这些数组中的每一个都有两列。

当我尝试计算距离时using scipy.spatial.distance.cdist,出现以下错误:

in haversine(x, y)
      6     # convert decimal degrees to radians
      7     print(type(x))
---->; 8     lat1,lon1 =np.radians(x)
      9     lat2,lon2 = np.radians(y)
     10 

TypeError: 'numpy.float64' object is not iterable

haversine似乎认为输入x是浮点数而不是数组。即使我将数组传递给haversine类似haversine(np.zeros(2),np.zeros(2))的问题也会出现。我应该注意,这仅在通过np.vectorize.

从 看haversine,论点没有以任何方式改变。什么可能导致错误?

这是一个最小的工作示例:

import numpy as np
from scipy.spatial.distance import cdist

gas_coords = np.array([[50, 80], [50, 81]])
postal_coords = np.array([[51, 80], [51, 81]])


cdist(postal_coords, gas_coords, metric = haversine)


>>>array([[ 111.19492664,  131.7804742 ],
          [ 131.7804742 ,  111.19492664]])

标签: pythonnumpy

解决方案


给定所需的输出,可以通过不对haversine函数进行向量化来避免错误,因为这会将标量传递给函数(如上面的注释中所述)。所以你可以打电话cdist

import numpy as np
from scipy.spatial.distance import cdist

def haversine(x, y):
    """
    Calculate the great circle distance between two points 
    on the earth (specified in decimal degrees)
    """
    # convert decimal degrees to radians 
    print(type(x))
    lat1, lon1 = np.radians(x)
    lat2, lon2 = np.radians(y)

    # haversine formula 
    dlon = lon2 - lon1 
    dlat = lat2 - lat1 
    a = np.sin(dlat/2)**2 + np.cos(lat1) * np.cos(lat2) * np.sin(dlon/2)**2
    c = 2 * np.arcsin(np.sqrt(a)) 
    r = 6371 # Radius of earth in kilometers. Use 3956 for miles
    return c * r

gas_coords = np.array([[50, 80], [50, 81]])
postal_coords = np.array([[51, 80], [51, 81]])

cdist(postal_coords, gas_coords, metric=haversine)

推荐阅读