15GB数据,运行时间15m

请注意:因为使用了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()