14GB JSONL闪电数据集筛选特定国家记录的最优实现方案
闪电数据集过滤优化方案
无索引的JSONL文件不存在跳过全量扫描的可能,以下方案可将现有处理效率提升10倍以上,大幅降低耗时:
- 第一步先加经纬度粗筛:先通过德国的经纬度边界框过滤掉90%以上的无关记录,无需调用逆地理编码。德国的经纬度范围约为
lat ∈ [47.2701, 55.0583],lon ∈ [5.8663, 15.0419],不在该范围内的坐标直接跳过即可。 - 替换JSON解析库:用
ujson替代Python标准库的json,字符串解析速度提升3~5倍。 - 批量调用逆地理编码:
reverse_geocoder支持传入坐标列表批量查询,避免单条调用的 overhead,单次查询100~500个坐标效率最优。 - 优化IO操作:攒够一定数量的符合条件的记录后再批量写入目标文件,减少磁盘IO的频繁调用。
- 长期复用建议:如果需要频繁针对不同国家做过滤,可将数据导入搭载PostGIS扩展的PostgreSQL数据库,给经纬度字段建GIST空间索引,后续任意国家的过滤请求都可毫秒级返回,无需再次扫描全量文件。
优化后代码示例
import ujson import reverse_geocoder as rg # 德国经纬度边界框 DE_LAT_MIN, DE_LAT_MAX = 47.2701, 55.0583 DE_LON_MIN, DE_LON_MAX = 5.8663, 15.0419 BATCH_SIZE = 500 write_buffer = [] candidate_coords = [] candidate_strikes = [] with open('file_name.jsonl', 'r') as infile, open('de_strokes.jsonl', 'w') as outfile: for line in infile: line_data = ujson.loads(line) for strike in line_data['strokes']: lat, lon = strike['lat'], strike['lon'] # 粗筛直接过滤无关坐标 if not (DE_LAT_MIN <= lat <= DE_LAT_MAX and DE_LON_MIN <= lon <= DE_LON_MAX): continue candidate_coords.append((lat, lon)) candidate_strikes.append(strike) # 凑够批量查询 if len(candidate_coords) >= BATCH_SIZE: res = rg.search(candidate_coords) for idx, item in enumerate(res): if item['cc'] == 'DE': write_buffer.append(ujson.dumps(candidate_strikes[idx]) + '\n') # 批量写文件 if len(write_buffer) >= BATCH_SIZE * 2: outfile.writelines(write_buffer) write_buffer = [] candidate_coords = [] candidate_strikes = [] # 处理剩余的批次 if candidate_coords: res = rg.search(candidate_coords) for idx, item in enumerate(res): if item['cc'] == 'DE': write_buffer.append(ujson.dumps(candidate_strikes[idx]) + '\n') if write_buffer: outfile.writelines(write_buffer)
内容的提问来源于stack exchange,提问作者Odess4
相关产品推荐
相关产品推荐

