如何解决Python中‘float’ object is not iterable错误?基于距离分类DataFrame
按地理距离对DataFrame地点分类问题解决
需求说明
我是Python新手,需要根据df2中地点的距离对df1中的地点分类:计算df1每个地点与df2所有地点的直线距离,只要存在任意一个df2地点距离小于1000米,就标记为close,否则标记为far。
已创建的两个坐标DataFrame:
import pandas as pd import geopy.distance df1 = pd.DataFrame([['a', 55.88, 37.48], ['b', 55.88, 37.53], ['c', 55.89, 37.45]], columns=['name', 'lat', 'lng']) df2 = pd.DataFrame([['f', 55.81, 37.12], ['g', 55.79, 37.23], ['h', 55.23, 37.21]], columns=['name', 'lat', 'lng'])
df1数据:
| name | lat | lng |
|---|---|---|
| a | 55.88 | 37.48 |
| b | 55.88 | 37.53 |
| c | 55.89 | 37.45 |
df2数据:
| name | lat | lng |
|---|---|---|
| f | 55.81 | 37.12 |
| g | 55.79 | 37.23 |
| h | 55.23 | 37.21 |
期望输出的df1结果:
| name | lat | lng | dist_to_place |
|---|---|---|---|
| a | 55.88 | 37.48 | far |
| b | 55.88 | 37.53 | close |
| c | 55.89 | 37.45 | far |
原代码错误分析
我尝试的代码运行时报错'float' object is not iterable,问题出在这几个地方:
- 使用
df1.apply(dist, axis=1)时,函数会把df1的每一行数据传给dist函数,而不是整个df1,原函数定义def dist(df1)后又用for i in range(len(df1))遍历,逻辑完全错误 - 代码里用了未定义的
data和metro变量,应该是df1和df2 - 循环逻辑错误:只要第一个df2地点不满足距离<1000米,就直接返回
far,没有遍历完所有df2地点就提前返回,不符合需求
原错误代码:
def dist(df1): for i in range(len(df1)): for j in range(len(df2)): if geopy.distance.geodesic( tuple(data[['lat','lng']].iloc[i]), tuple(metro[['lat','lng']].iloc[j])).m <1000: return 'close' else: return 'far' df1['dist_to_place'] = df1.apply(dist, axis=1)
修正后的解决方案
调整函数逻辑,让它接收df1的每行数据,遍历所有df2地点检查距离:
def dist(df1_row): # 遍历df2的所有地点 for j in range(len(df2)): # 计算当前df1行与df2第j个地点的距离(单位:米) distance = geopy.distance.geodesic( tuple(df1_row[['lat','lng']]), tuple(df2[['lat','lng']].iloc[j])).m if distance < 1000: # 只要有一个地点距离达标,直接返回close return 'close' # 遍历完所有df2地点都不达标,返回far return 'far' # 给df1添加分类列 df1['dist_to_place'] = df1.apply(dist, axis=1)
验证结果
运行修正后的代码后,df1会得到期望的结果:
| name | lat | lng | dist_to_place |
|---|---|---|---|
| a | 55.88 | 37.48 | far |
| b | 55.88 | 37.53 | close |
| c | 55.89 | 37.45 | far |
内容的提问来源于stack exchange,提问作者иван синев
相关产品推荐
相关产品推荐

