请注意:因为使用了jupyter notebook 的 cython magic, 此notebook中的代码仅可以在 jupyter notebook 下可用,代码下载到python文件无法正常运行
In [1]:
%load_ext cython #使用cython扩展
In [2]:
%%cython
# 使用cython 加快点是否在矩形内的判定
cdef struct Rect: # 定义范围矩形,便于加快查找速度
float lon_min
float lon_max
float lat_min
float lat_max
cpdef int in_range_c(object point, object rect): # 查找点是否在矩形内
cdef float lon, lat
cdef Rect r1
lon, lat = point
r1.lon_min, r1.lon_max, r1.lat_min, r1.lat_max = rect
if lon < r1.lon_min or lon > r1.lon_max:
return False
if lat < r1.lat_min or lat > r1.lat_max:
return False
return True
In [3]:
from glob import glob
flickr_datas = glob('*.txt') # 将当前需要处理的文件名提取到列表,此处是txt文件,可以手动改成其他文件
poi_data = 'POI.csv'
pois = {} # POI 字典,键为 地点名, 值为四至点范围
with open(poi_data) as f:
for line in f:
l = line.strip().split(',')
pois[l[-1].encode()] = [float(i) for i in l[:-1]]
for k, v in pois.items():
pois[k] = sorted([v[1], v[3]]) + sorted([v[0], v[2]]) # [lon_min, lon_max, lat_min, lat_max]]
In [4]:
for file in flickr_datas: # 只遍历一次所有文件
with open(file, 'rb') as f, open('total.csv', 'ab') as g: # 使用二进制读写,显著加快IO速度
for line in f:
coordinates = [float(i) for i in line.split(b'\t')[7:9]] # [lon, lat]
for site, rect in pois.items():
if in_range_c(coordinates, rect):
g.write(site + b'\t' + line) # 将所有的搜索结果加上地名写到一个文件下,待稍后处理
In [5]:
file_dict = {}
with open('total.csv', encoding='utf-8') as f: # 将汇总的文件分开成多个小文件
for line in f:
site = line.split('\t')[0]
if site not in file_dict:
file_dict[site] = open('{}.csv'.format(site), 'w', encoding='utf-8')
file_dict[site].write(line.split('\t', 1)[1])
for site, file in file_dict.items():
file.close()