基于指定列实现两个DataFrame列相减的技术求助
问题:基于匹配列对两个DataFrame的Intensity列进行相减操作
我来帮你搞定这个DataFrame列相减的需求,针对你提供的两个质谱数据集,我们可以用Python的pandas库轻松实现,下面分两种匹配场景给出具体方案:
数据集说明
MSdata1
| m.z | Intensity | Relative | Delta..ppm. | RDB.equiv. | Composition |
|---|---|---|---|---|---|
| 301.14093 | 7646 | 100.00 | -0.34 | 5.5 | C16 H22 O4 Na |
| 149.02331 | 4083458.5 | 23.60 | -0.08 | 6.5 | C8 H5 O3 |
| 279.15908 | 33256 | 18.64 | -0.03 | 5.5 | C16 H23 O4 |
MSdata2
| m.z | Intensity | Relative | Delta..ppm. | RDB.equiv. | Composition |
|---|---|---|---|---|---|
| 331.11233 | 4324 | 94.00 | -0.33 | 6.5 | C17 H26 O5 Na |
| 149.02331 | 4083458.5 | 23.60 | -0.08 | 6.5 | C8 H5 O3 |
| 279.15908 | 42315 | 18.64 | -0.03 | 5.5 | C16 H23 O4 |
解决方案(基于pandas)
首先确保你已经安装了pandas:pip install pandas
方案1:基于Composition列匹配并计算Intensity差值
这个方案适合Composition作为唯一标识的场景,直接按Composition合并两个DataFrame后做减法:
import pandas as pd # 创建MSdata1的DataFrame(如果是从文件读取,用pd.read_csv("ms1.csv")即可) ms1_data = [ [301.14093, 7646, 100.00, -0.34, 5.5, "C16 H22 O4 Na"], [149.02331, 4083458.5, 23.60, -0.08, 6.5, "C8 H5 O3"], [279.15908, 33256, 18.64, -0.03, 5.5, "C16 H23 O4"] ] ms1_df = pd.DataFrame(ms1_data, columns=["m.z", "Intensity", "Relative", "Delta..ppm.", "RDB.equiv.", "Composition"]) # 创建MSdata2的DataFrame ms2_data = [ [331.11233, 4324, 94.00, -0.33, 6.5, "C17 H26 O5 Na"], [149.02331, 4083458.5, 23.60, -0.08, 6.5, "C8 H5 O3"], [279.15908, 42315, 18.64, -0.03, 5.5, "C16 H23 O4"] ] ms2_df = pd.DataFrame(ms2_data, columns=["m.z", "Intensity", "Relative", "Delta..ppm.", "RDB.equiv.", "Composition"]) # 按Composition合并,保留所有行(outer join),用后缀区分两个数据集的列 merged_df = pd.merge(ms1_df, ms2_df, on="Composition", suffixes=("_ms1", "_ms2"), how="outer") # 计算Intensity差值(MSdata1 - MSdata2),空值用0填充 merged_df["Intensity_Diff"] = merged_df["Intensity_ms1"].fillna(0) - merged_df["Intensity_ms2"].fillna(0) # 查看核心结果 print(merged_df[["Composition", "Intensity_ms1", "Intensity_ms2", "Intensity_Diff"]])
运行后会得到如下核心结果:
| Composition | Intensity_ms1 | Intensity_ms2 | Intensity_Diff |
|---|---|---|---|
| C16 H22 O4 Na | 7646.0 | NaN | 7646.0 |
| C8 H5 O3 | 4083458.5 | 4083458.5 | 0.0 |
| C16 H23 O4 | 33256.0 | 42315.0 | -9059.0 |
| C17 H26 O5 Na | NaN | 4324.0 | -4324.0 |
方案2:基于m.z列匹配并计算差值
因为m.z是浮点数值,直接匹配可能存在精度问题,这里提供两种处理方式:
方式A:四舍五入后精确匹配
对m.z保留固定小数位后再合并,避免浮点精度干扰:
# 对m.z保留4位小数(可根据你的数据精度调整) ms1_df["m.z_rounded"] = ms1_df["m.z"].round(4) ms2_df["m.z_rounded"] = ms2_df["m.z"].round(4) # 按四舍五入后的m.z合并 merged_df_mz = pd.merge(ms1_df, ms2_df, on="m.z_rounded", suffixes=("_ms1", "_ms2"), how="outer") # 计算差值 merged_df_mz["Intensity_Diff"] = merged_df_mz["Intensity_ms1"].fillna(0) - merged_df_mz["Intensity_ms2"].fillna(0) # 查看结果 print(merged_df_mz[["m.z_rounded", "Intensity_ms1", "Intensity_ms2", "Intensity_Diff"]])
方式B:近似值匹配(merge_asof)
如果需要更灵活的精度控制,用merge_asof实现近似匹配:
# merge_asof要求数据集按匹配列排序 ms1_sorted = ms1_df.sort_values("m.z") ms2_sorted = ms2_df.sort_values("m.z") # 按m.z近似匹配,容差设为0.0001(可根据需求调整) merged_asof = pd.merge_asof( ms1_sorted, ms2_sorted, on="m.z", suffixes=("_ms1", "_ms2"), tolerance=0.0001, direction="nearest" ) # 计算差值 merged_asof["Intensity_Diff"] = merged_asof["Intensity_ms1"] - merged_asof["Intensity_ms2"].fillna(0) # 查看结果 print(merged_asof[["m.z", "Composition_ms1", "Composition_ms2", "Intensity_ms1", "Intensity_ms2", "Intensity_Diff"]])
注意事项
- 如果你的数据是从CSV/Excel读取的,直接用
pd.read_csv("your_file.csv")或pd.read_excel("your_file.xlsx")即可,无需手动创建DataFrame - 浮点型m.z的匹配一定要注意精度问题,避免因微小数值差异导致匹配失败
- 如果只需要保留两个数据集都存在的匹配行,把merge的
how参数改为inner即可
内容的提问来源于stack exchange,提问作者Ragstock
相关产品推荐
相关产品推荐

