# Python实践 | 亿级经纬度距离计算工具V2

```1import pandas as pd
2import numpy as np
3from math import radians, cos, sin, asin, sqrt, ceil
4import math
5import time```

```1def geodistance(lng1,lat1,lng2,lat2):
2    lng1, lat1, lng2, lat2 = map(radians, [float(lng1), float(lat1), float(lng2), float(lat2)])
3    # 经纬度转换成弧度
4    dlon=lng2-lng1
5    dlat=lat2-lat1
6    a=sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
7    distance=2*asin(sqrt(a))*6371*1000 # 地球平均半径，6371km
8    distance=round(distance,0)
9    return distance```

`pandas`分别导入源表和目标表，两个表关联得到原点与目标点的所有配对

```1file_name = r'D:\python\geo\sTable.csv'
3file_name2 = r'D:\python\geo\tTable.csv'
5m = pd.concat([pd.concat([df1]*len(df2)).sort_index().reset_index(drop=True),
6               pd.concat([df2]*len(df1)).reset_index(drop=True) ], 1)```

```    x = m[abs(m.lon-m.lon2) < diff_lon]
n = x[abs(x.lat-x.lat2) < diff_lat]```

```    nn = n.copy()
nn['distance'] = nn.apply(lambda ser: geodistance(ser['lon'], ser['lat'], ser['lon2'], ser['lat2']), axis=1)```

`1distance = distance.append(nn[nn.distance <= minx_mile])`

`1pieces = ceil(count_a * count_b / 10000000)   # 计算量上限为1000万`

`1linesPerFile = ceil(count_a / pieces)+1`

``` 1filecount = 1
2# 以0为起点，文件行数为终点，分片大小为间隔，循环遍历文件，每次遍历行数即为分片大小，而不是每行遍历一次，处理效率极高，但是比较吃内存
3for i in range(0, len(csv_file), linesPerFile):
4    # 打开目标文件准备写入，不存在则创建
5    with open(file_name[:-4] + '_' + str(filecount) + '.csv', 'w+') as f:
6        # 判断是否为第一个文件，不是的话需要先写入标题行
7        if filecount > 1:
8            f.write(csv_file[0])
9        # 批量写入i至i+分片大小的多行数据，效率极高
10        f.writelines(csv_file[i:i+linesPerFile])
11    # 完成一个文件写入之后，文件编号增加1
12    filecount += 1```

```distance = pd.DataFrame(columns=('name','lon','lat','name2', 'lon2', 'lat2', 'distance'))
for i in range(1, filecount):
df_temp = pd.read_csv(file_name[:-4] + '_' + str(i) + '.csv')
m = pd.concat([pd.concat([df_temp]*len(df2)).sort_index().reset_index(drop=True),
pd.concat([df2]*len(df_temp)).reset_index(drop=True)], 1)
# 避免链式赋值
x = m[abs(m.lon-m.lon2) < diff_lon]
n = x[abs(x.lat-x.lat2) < diff_lat]
nn = n.copy()
nn['distance'] = nn.apply(lambda ser: geodistance(ser['lon'], ser['lat'], ser['lon2'], ser['lat2']), axis=1)
distance = distance.append(nn[nn.distance <= minx_mile])
distance.to_csv('D:/python/geo/distance_result.csv')```

0 条评论

• ### Python实践 | 亿级经纬度距离计算代码实现

计算经纬度的代码网上一搜一大把，通常是单点距离的计算，无法实现批量计算，本文将利用pandas实现亿级经纬度距离代码的实现。 最短距离计算建议参考下文，mapi...

• ### 利用Python批量合并csv

前几天遇到一个工作，需要将几个分别包含几十万行的csv文件的某3列合并成1个csv文件，当时是手工合并的： 1、csv另存为excel； 2、删除不需要的列，仅...

• ### 利用Python进行CSV文件编码检测

csv文件编码格式多种多样，批量处理时容易出现问题，今天偶然看到有人提问：如何处理PowerBI批量导入csv文件时，文件编码不一致的问题？因为我之前处理过单个...

• ### 人类基因组时代的泛基因组学

今天想分享一个主题：人类基因组时代的泛基因组学。主要内容源自今年《Nature Reviews Genetics》上一篇题为《Pan-genomics in t...

• ### 程序员奶爸的心路历程：如何在一年内获得五项开发者认证和第二学位

原作者 Beau Carnes 编译 CDA 编译团队 本文为 CDA 数据分析师原创翻译作品，转载需授权 前言 工作和家庭难以兼顾吗？美国程序员小哥实力演绎如...

• ### Linux命令（26）——rename命令

功能类似于mv，可实现文件或者目录的重命名，mv不能批量处理，而rename可以。

• ### PHP中rename()函数的妙用讲解

大家都知道，rename()函数可以对文件或目录进行重命名的操作。其实它还可以做很多事情。

• ### 如何让局域网内的其他人访问到自己在Tomcat上部署的项目

学JSP第三节课，今天老师上课讲了开启Tomcat之后，将自己电脑的文件放到指定的目录下，可以让同宿舍的人访问并且下载，老师只是提了一下，没有具体讲，后来我看...