如何查找距离 b/w 地理位置 w/ 测地线 w/ 坐标分为 4 个不同的列以创建距离列--ValueError

Posted

技术标签:

【中文标题】如何查找距离 b/w 地理位置 w/ 测地线 w/ 坐标分为 4 个不同的列以创建距离列--ValueError【英文标题】:How to Find Distance b/w Geographic Locations w/ Geodesic w/ Coordinates Separated Into 4 Different Columns To Create a Distance Column--ValueError 【发布时间】:2020-09-20 07:39:39 【问题描述】:

我创建了一个更短的假数据集。我已将我的 Location_1 和 Location_2 分成两列,总共产生四列。现在我需要在上面使用geodesic。在进行测试运行时,我可以通过一次观察手动完成。但我似乎无法使其适用于整个数据列,也无法为距离创建新列。

下面的代码将一直运行到最后一行,它抛出一个错误并反映了我对原始日期集的处理,我无法共享并且是数千个观察结果。敲出来的线也抛出了一个错误,但是一个不同的错误。

 places_data = pd.DataFrame(
     "Place_1": ["Disneyland Park", "Empire State Building", "Yosemite Park", "Disney World Park", "Rockefeller Tower", "Grand Canyon"],   
      "Places": ["Peaches", "Apples", "Peaches", "Peaches", "Apples", "Peaches"]
      )

 other_places = places_data.copy()

 other_places.loc[(other_places["Places"] == "Peaches"), "Sites"] = "Georgia Aquarium"
 other_places.loc[(other_places["Places"] == "Apples"), "Sites"] = "World of Coca-Cola"
 
 other_places["Loc_1"] = other_places["Place_1"].apply(geolocator.geocode).apply(lambda loc: tuple(loc.point) if loc else None)
 other_places["Loc_2"] = other_places["Sites"].apply(geolocator.geocode).apply(lambda loc: tuple(loc.point) if loc else None)

 places_data['Loc_1'] = places_data.Place_1.map(dict(other_places[['Place_1','Loc_1']].to_numpy()))
 places_data['Loc_2'] = places_data.Places.map(dict(other_places[['Places','Loc_2']].to_numpy()))

 places_data[['Lat_1', 'Long_1', 'Alt_1']] = pd.DataFrame(places_data['Loc_1'].tolist(), index = places_data.index)
 places_data[['Lat_2', 'Long_2', 'Alt_2']] = pd.DataFrame(places_data['Loc_2'].tolist(), index = places_data.index)

 #places_data["Distance"] = geodesic(places_data["Loc_1"], places_data["Loc_2"]).miles

 places_data["Distance"] = geodesic(
          (places_data["Lat_1"], places_data["Long_1"]),
          (places_data["Lat_2"], places_data["Long_2"])
     ).miles

这是我的有效测试代码

 geodesic(
     (geolocator.geocode("Disneyland Park").latitude, geolocator.geocode("Disneyland Park").longitude), 
     (geolocator.geocode("World of Coca-Cola").latitude, geolocator.geocode("Disneyland Park").longitude)
      )

返回:距离(5.629067391427556)

错误总结:

ValueError:Series 的真值不明确。使用a.empty, a.bool()、a.item()、a.any() 或 a.all()。

这是错误:

--------------------------------------------------------------------------- ValueError                                Traceback (most recent call last) <ipython-input-772-f5a592d7d527> in <module>()
     22 places_data["Distance"] = geodesic(
     23     (places_data["Lat_1"], places_data["Long_1"]),
---> 24     (places_data["Lat_2"], places_data["Long_2"])
     25     ).miles

7 frames /usr/local/lib/python3.6/dist-packages/geopy/distance.py in
__init__(self, *args, **kwargs)
    387         kwargs.pop('iterations', 0)
    388         major, minor, f = self.ELLIPSOID
--> 389         super(geodesic, self).__init__(*args, **kwargs)
    390 
    391     def set_ellipsoid(self, ellipsoid):

/usr/local/lib/python3.6/dist-packages/geopy/distance.py in
__init__(self, *args, **kwargs)
    162         elif len(args) > 1:
    163             for a, b in util.pairwise(args):
--> 164                 kilometers += self.measure(a, b)
    165 
    166         kilometers += units.kilometers(**kwargs)

/usr/local/lib/python3.6/dist-packages/geopy/distance.py in measure(self, a, b)
    408     # Call geographiclib routines for measure and destination
    409     def measure(self, a, b):
--> 410         a, b = Point(a), Point(b)
    411         lat1, lon1 = a.latitude, a.longitude
    412         lat2, lon2 = b.latitude, b.longitude

/usr/local/lib/python3.6/dist-packages/geopy/point.py in __new__(cls, latitude, longitude, altitude)
    169                     )
    170                 else:
--> 171                     return cls.from_sequence(seq)
    172 
    173         if single_arg:

/usr/local/lib/python3.6/dist-packages/geopy/point.py in from_sequence(cls, seq)
    408             raise ValueError('When creating a Point from sequence, it '
    409                              'must not have more than 3 items.')
--> 410         return cls(*args)
    411 
    412     @classmethod

/usr/local/lib/python3.6/dist-packages/geopy/point.py in __new__(cls, latitude, longitude, altitude)
    181 
    182         latitude, longitude, altitude = \
--> 183             _normalize_coordinates(latitude, longitude, altitude)
    184 
    185         self = super(Point, cls).__new__(cls)

/usr/local/lib/python3.6/dist-packages/geopy/point.py in
_normalize_coordinates(latitude, longitude, altitude)
     63 
     64 def _normalize_coordinates(latitude, longitude, altitude):
---> 65     latitude = float(latitude or 0.0)
     66     longitude = float(longitude or 0.0)
     67     altitude = float(altitude or 0.0)

/usr/local/lib/python3.6/dist-packages/pandas/core/generic.py in
__nonzero__(self)    1477     def __nonzero__(self):    1478         raise ValueError(
-> 1479             f"The truth value of a type(self).__name__ is ambiguous. "    1480             "Use a.empty, a.bool(), a.item(), a.any() or a.all()."    1481         )

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

【问题讨论】:

【参考方案1】:

在列表理解zip 中,Loc_1Loc_2 的列并计算每对 loc_1loc_2geodesic 距离:

places_data['Distance'] = [geodesic(x, y).miles for x, y in zip(places_data['Loc_1'], places_data['Loc_2'])]

0    1920.542230
1     748.136742
2    1587.254446
3     406.942672
4    1918.193488
5    1575.644170
Name: Distance, dtype: float64

【讨论】:

@EX_Tenn 这是否回答了您的问题?如果是这样,您可以接受并投票赞成答案。看看What should I do when someone answers my question?

以上是关于如何查找距离 b/w 地理位置 w/ 测地线 w/ 坐标分为 4 个不同的列以创建距离列--ValueError的主要内容,如果未能解决你的问题,请参考以下文章

Linq 查询 - 根据第一个字母 b/w 两个范围查找字符串

R中具有测地线或大圆距离的空间测地纬度经度聚类的方法

将测地线数据类型更改为整数

网格测地线算法(Geodesics in Heat)附源码

文件操作的函数

如何在MySQL中加入查询以根据距离计算和Google地理编码查找WordPress帖子?