如何用Bash按列分组生成新DataFrame?求脚本修正及简化方案
按列分组取最值并输出指定格式行
输入数据
chr1,A,1,3,y,- chr1,A,2,30,y,- chr1,A,12,40,y,- chr2,B,0,3,y,- chr2,B,1,30,y,- chr3,C,1,3,y,-
需求
按第2列(如A、B、C)分组,每组保留第1、2、5、6列的固定内容,将第3列替换为该组的最小值,第4列替换为该组的最大值,输出格式如下:
chr1,A,1,40,y,- chr2,B,0,30,y,- chr3,C,1,3,y,-
当前脚本问题分析
你编写的awk脚本错误在于:每次循环都会把row[$2]覆盖为当前行的原始内容,最终输出的是每组最后一行的原始第3、4列值,而非统计得到的最小值和最大值。
正确的awk实现
修改思路:单独存储每组的固定字段(第1、2、5、6列),同时维护每组的第3列最小值和第4列最大值,最后在END块中组合这些值输出:
BEGIN{FS=OFS=","} { key = $2 if (!(key in min)) { min[key] = $3 max[key] = $4 # 存储固定不变的前后段字段 prefix[key] = $1 OFS $2 suffix[key] = $5 OFS $6 } else { if ($3 < min[key]) min[key] = $3 if ($4 > max[key]) max[key] = $4 } } END{ for (key in min) { print prefix[key], min[key], max[key], suffix[key] } }
执行该脚本即可得到期望输出。
更简洁的awk写法
可以简化变量存储逻辑,直接用数组维护每组关键值:
BEGIN{FS=OFS=","} { k=$2 if(!(k in min) || $3 < min[k]) min[k]=$3 if(!(k in max) || $4 > max[k]) max[k]=$4 if(!(k in head)) head[k] = $1 OFS $2 if(!(k in tail)) tail[k] = $5 OFS $6 } END{for(k in head) print head[k], min[k], max[k], tail[k]}
内容的提问来源于stack exchange,提问作者Apex
相关产品推荐
相关产品推荐

