如何在Pandas DataFrame中对重复样本按列分组并计算均值
优雅处理多级表头的重复样本数据(无需依赖文件名规律)
当然可以!完全不用纠结重复文件名的命名规律,咱们直接用Pandas的多级列和重塑功能就能搞定,而且全程在DataFrame里操作,非常简洁。下面跟着示例一步步来:
1. 先构建示例多级列DataFrame
首先把你给出的原始数据转换成Pandas的多级表头格式:
import pandas as pd # 原始数据的两行表头 sample_names = ['S1', 'S1', 'S2', 'S2'] file_names = ['S1.1', 'S1.2', 'S2.1', 'S2.2'] # 构建多级列索引 multi_cols = pd.MultiIndex.from_arrays([sample_names, file_names], names=['Sample', 'File']) # 构建数据部分 data = [ [10, 8, 14, 1], [0, 6, 2, 3] ] # 创建DataFrame df = pd.DataFrame(data, index=['Ion1', 'Ion2'], columns=multi_cols)
此时的df就是和你原始数据一致的多级表头结构啦。
2. 重塑数据到目标格式
接下来咱们一步步把它转成你想要的结构:
步骤1:把索引(Ion)转为普通列
这样方便后续的分组和重塑:
df = df.reset_index().rename(columns={'index': 'Ion'})
步骤2:将宽格式数据转为长格式
用melt方法把每一列的测量值拆成单独的行,同时保留对应的样本名和文件名:
df_long = df.melt(id_vars='Ion', var_name=['Sample', 'File'], value_name='Value')
这一步之后,每一行都是一个离子+样本+文件名的测量值,完全脱离了原有的宽格式限制,而且完全不依赖文件名的规律——我们只需要用到Sample这一级的信息。
步骤3:给每个样本的重复测量编号
对每个Ion+Sample的组合,给重复测量按顺序标上Rep1、Rep2:
# 给每个组内的测量值编序号(从1开始) df_long['Rep'] = df_long.groupby(['Ion', 'Sample']).cumcount() + 1 # 把序号转成Rep1、Rep2这样的列名 df_long['Rep'] = 'Rep' + df_long['Rep'].astype(str)
步骤4:重塑回宽格式得到目标结构
用pivot把重复测量值转为列:
result = df_long.pivot(index=['Ion', 'Sample'], columns='Rep', values='Value').reset_index() # 调整列顺序,让它和你想要的格式一致 result = result[['Ion', 'Sample', 'Rep1', 'Rep2']]
此时的result就是你要的格式:
| Ion | Sample | Rep1 | Rep2 | |
|---|---|---|---|---|
| 0 | Ion1 | S1 | 10 | 8 |
| 1 | Ion1 | S2 | 14 | 1 |
| 2 | Ion2 | S1 | 0 | 6 |
| 3 | Ion2 | S2 | 2 | 3 |
3. 计算重复样本的均值
得到目标格式后,计算均值就非常简单了:
result['Mean'] = result[['Rep1', 'Rep2']].mean(axis=1)
最终结果会多一列均值,完美满足你的需求。
核心优势
整个过程完全没有用到文件名(比如S1.1、S2.2)的任何规律,所有分组都是基于第一行的样本名(多级列的Sample层级)来完成的,不管你的文件名是XF20114还是其他无规律名称,都能正常工作。
内容的提问来源于stack exchange,提问作者Laughable oxen
相关产品推荐
相关产品推荐

