如何按类别提取多行无表头数据的最大值与最小值
问题背景
你有一份无表头的分类数据集(第一列为类别,后续列为数值),需要按类别提取所有对应数值的最大值和最小值:
输入数据:
Class A 5 9 2 6 A 13 8 A 4 8 3 10 6 B 12 5 11 B 7 1 17 6 8 1期望输出(注:原需求中B类的最大值33应为笔误,实际最大数值是17):
Class Max Min A 13 2 B 17 1
方法1:Python Pandas 实现
如果你习惯用Python做数据处理,Pandas可以轻松搞定这类分组统计需求:
- 先读取数据,处理行长度不一的情况(因为不同行的数值列数量不同)
- 将每个类别对应的所有数值展开成单条记录
- 按类别分组计算最大最小值
import pandas as pd # 读取文本数据,用空格分隔,第一行作为表头 df = pd.read_csv('your_data_file.txt', sep='\s+', header=0) # 遍历每行,收集每个类别对应的所有数值 all_values = [] for _, row in df.iterrows(): class_label = row['Class'] # 提取当前行的所有数值(过滤空值,因为短行后面会有NaN) numbers = [val for val in row[1:] if pd.notna(val)] # 把每个数值和类别配对加入列表 for num in numbers: all_values.append({'Class': class_label, 'Value': num}) # 转换成新的DataFrame,方便分组统计 value_df = pd.DataFrame(all_values) # 分组计算最大、最小值,并重命名列 result = value_df.groupby('Class')['Value'].agg(['max', 'min']).reset_index() result.columns = ['Class', 'Max', 'Min'] # 打印结果(去掉索引) print(result.to_string(index=False))
运行这段代码后,就能得到你需要的统计结果。
方法2:Awk 命令行快速处理
如果不想写Python脚本,用Awk工具可以直接在命令行完成处理,适合快速处理文本文件:
创建一个process_stats.awk文件,写入以下内容:
# 跳过第一行的表头 NR == 1 { next } # 处理每一行的数值 { current_class = $1 # 遍历当前行的所有数值(从第2列开始) for (i = 2; i <= NF; i++) { num = $i # 初始化当前类别的最大最小值 if (!(current_class in max_vals)) { max_vals[current_class] = num min_vals[current_class] = num } # 更新最大值 if (num > max_vals[current_class]) { max_vals[current_class] = num } # 更新最小值 if (num < min_vals[current_class]) { min_vals[current_class] = num } } } # 所有行处理完后输出结果 END { print "Class Max Min" # 遍历所有类别输出统计值 for (cls in max_vals) { printf "%s %d %d\n", cls, max_vals[cls], min_vals[cls] } }
然后在命令行执行:
awk -f process_stats.awk your_data_file.txt
同样会输出正确的统计结果。
内容的提问来源于stack exchange,提问作者Adam Amin




