使用awk计算大尺寸OD对称矩阵的技术求助
处理超大OD矩阵生成对称下三角矩阵(解决内存不足问题)
核心思路
- 排序输入:将OD记录按
origin_id→destination_id升序排列,确保(i,j)(i<j)先于(j,i)出现,实现流式处理,无需存储全量数据。 - 单脚本处理:通过小型数组暂存未匹配的
(i,j)记录,遇到反向对时立即计算对称值并输出,同时直接过滤下三角+对角线元素,避免二次处理和内存溢出。
具体步骤
1. 排序输入文件
通过管道直接将排序后的数据流传给awk,无需生成中间文件:
sort -t ',' -k1,1 -k2,2 inputfile.csv | awk -f symm_opt.awk > output.csv
若需保留排序后的文件,执行:
sort -t ',' -k1,1 -k2,2 inputfile.csv > sorted_input.csv
2. 优化后的awk脚本(symm_opt.awk)
BEGIN { FS = OFS = "," print "\"origin_id\",\"destination_id\",\"trips\"" } NR > 1 { o = $1 d = $2 gsub(/"/, "", $3) t = $3 + 0 if (o == d) { print o, d, "\"" t "\"" next } if (o < d) { arr[o FS d] = t next } key = d FS o if (key in arr) { avg = (arr[key] + t) / 2 print d, o, "\"" avg "\"" delete arr[key] } else { avg = t / 2 print d, o, "\"" avg "\"" } } END { for (key in arr) { split(key, parts, FS) avg = arr[key] / 2 print parts[1], parts[2], "\"" avg "\"" } }
脚本说明
- 内存高效:仅暂存未匹配到反向对的
o<d记录,处理后立即删除,内存占用仅为原脚本的极小部分,适配31GB超大文件。 - 一步到位:直接输出符合要求的对角线+下三角元素,无需二次awk调用。
- 输出有序:基于排序后的输入,输出自动按
origin_id和destination_id升序排列。
测试结果
用示例输入验证,脚本输出与期望完全一致:
"origin_id","destination_id","trips" "0","0","20" "0","1","17.5" "0","2","4" "1","1","50" "1","2","7.5" "2","2","33"
内容的提问来源于stack exchange,提问作者ElTitoFranki
相关产品推荐
相关产品推荐

