如何按第一列ID分组,筛选每组第二列最小值的所有行?
这问题我之前处理类似的日志数据时碰到过,用Python或者awk都能轻松解决,下面给你两种实用的方案:
方案1:用Python处理(适合需要自定义逻辑或集成到脚本的场景)
先把输入数据转换成成对的分组-值列表,再分组计算最小值,最后筛选出符合条件的项。代码如下:
# 输入数据 input_data = "1 7.8e-12 1 7.8e-12 1 1.0e-11 2 9.3e-13 2 3.5e-12 2 3.5e-10 2 3.1e-9 3 3.0e-11 3 3.0e-11 3 1.7e-08" # 分割成单个元素列表,每两个一组打包成(分组ID, 数值)的元组 elements = input_data.split() pairs = [(int(elements[i]), float(elements[i+1])) for i in range(0, len(elements), 2)] # 计算每个分组的最小值 group_min = {} for group, val in pairs: if group not in group_min or val < group_min[group]: group_min[group] = val # 筛选出值等于对应分组最小值的项 filtered = [] for group, val in pairs: if val == group_min[group]: filtered.extend([str(group), f"{val:.1e}"]) # 保持科学计数法格式 # 输出结果 print(' '.join(filtered))
代码说明:
- 先将输入字符串按空格拆分,再按步长2遍历,把每两个元素转成便于处理的(分组ID, 数值)元组。
- 用字典
group_min记录每个分组的最小值,遍历所有对时动态更新最小值。 - 再次遍历所有对,提取出值等于对应分组最小值的项,拼接成你需要的输出格式。
- 运行后会直接输出:
1 7.8e-12 1 7.8e-12 2 9.3e-13 3 3.0e-11 3 3.0e-11
方案2:用awk命令行处理(适合Linux/Unix环境下快速处理文本)
如果是在终端里快速处理,一行awk命令就能搞定:
echo "1 7.8e-12 1 7.8e-12 1 1.0e-11 2 9.3e-13 2 3.5e-12 2 3.5e-10 2 3.1e-9 3 3.0e-11 3 3.0e-11 3 1.7e-08" | awk '{ # 存储所有分组-值对,同时记录每个分组的最小值 for(i=1; i<=NF; i+=2) { group = $i val = $(i+1) pairs[NR, i] = group " " val if (!(group in min_val) || val < min_val[group]) { min_val[group] = val } } } END { # 遍历所有存储的对,筛选出符合条件的项并打印 for(key in pairs) { split(pairs[key], arr, " ") group = arr[1] val = arr[2] if (val == min_val[group]) { printf "%s ", pairs[key] } } printf "\n" }'
命令说明:
- 用
echo将输入数据传给awk,主处理块遍历所有字段,步长2,把每对分组和值存入数组,同时维护分组最小值字典。 - 在END块中遍历所有存储的对,判断值是否等于对应分组的最小值,符合条件就打印输出。
内容的提问来源于stack exchange,提问作者Anna1364
相关产品推荐
相关产品推荐

