如何移除两个质谱数据列表中的非匹配时间点数据?
质谱数据归一化:对齐时间点并过滤不匹配行
问题背景
我通过pymzml扫描质谱图,从各时间点提取两个特定m/z值,得到两组格式为[time, intensity, m/z]的数据列表。需要将其中一组(IS)的intensity归一化到另一组(AN),即计算IS_intensity / AN_intensity。
示例数据:
IS = [[1, 10, 122.076], [2, 40, 122.076], [3, 60, 122.076], ...] AN = [[1, 30, 146.117], [2, 80, 146.117], [3, 90, 146.117], ...]
原本计划用以下代码做归一化:
IS_arr = np.asarray(IS_intensity) AN_arr = np.asarray(AN_intensity) Norm_arr = np.divide(IS_arr, AN_arr) Norm_list = list(Norm_arr)
但实际中,两个m/z值并非在所有时间点都能被检测到(比如时间点6存在IS数据但无AN数据),导致两组数组形状不匹配,无法直接运算。需要移除所有不包含匹配时间点的行,确保时间点完全对齐后再执行归一化,避免生成无效数据。
解决方案
方法1:字典映射对齐(适合小型数据)
先将数据转为以时间为键的字典,筛选出共同时间点后重构对齐列表:
# 转换为{time: intensity}的字典结构 is_dict = {item[0]: item[1] for item in IS} an_dict = {item[0]: item[1] for item in AN} # 获取两组共有的时间点并排序 common_times = sorted(set(is_dict.keys()) & set(an_dict.keys())) # 提取对齐后的intensity列表 aligned_is_intensity = [is_dict[t] for t in common_times] aligned_an_intensity = [an_dict[t] for t in common_times] # 执行归一化 import numpy as np norm_arr = np.divide(aligned_is_intensity, aligned_an_intensity) norm_list = norm_arr.tolist()
该方法逻辑直观,无需额外依赖库,适合处理小规模数据。
方法2:Pandas内连接(适合大规模数据)
用Pandas的DataFrame做内连接,仅保留两边都存在的时间点,同时保留完整数据信息:
import pandas as pd # 转换为DataFrame并指定列名 df_is = pd.DataFrame(IS, columns=['time', 'is_intensity', 'is_mz']) df_an = pd.DataFrame(AN, columns=['time', 'an_intensity', 'an_mz']) # 按time字段做内连接,只保留匹配的时间点 merged_df = pd.merge(df_is, df_an, on='time', how='inner') # 计算归一化强度 merged_df['normalized_intensity'] = merged_df['is_intensity'] / merged_df['an_intensity'] # 可选:转换回原始列表格式 aligned_is = merged_df[['time', 'is_intensity', 'is_mz']].values.tolist() aligned_an = merged_df[['time', 'an_intensity', 'an_mz']].values.tolist() norm_list = merged_df['normalized_intensity'].tolist()
这种方法适合处理大规模数据,且方便后续的数据分析与可视化操作。
方法3:纯Numpy数组操作(适合Numpy工作流)
若已在Numpy环境下处理数据,可通过数组掩码筛选匹配时间点:
import numpy as np # 将列表转换为Numpy数组 is_arr = np.array(IS) an_arr = np.array(AN) # 提取两组的时间列 is_times = is_arr[:, 0] an_times = an_arr[:, 0] # 生成掩码,标记出存在于对方数组中的时间点 common_mask_is = np.isin(is_times, an_times) common_mask_an = np.isin(an_times, is_times) # 过滤得到对齐后的数组 aligned_is_arr = is_arr[common_mask_is] aligned_an_arr = an_arr[common_mask_an] # 可选:按时间排序(若原始数据时间无序) sorted_idx_is = np.argsort(aligned_is_arr[:, 0]) sorted_idx_an = np.argsort(aligned_an_arr[:, 0]) aligned_is_arr = aligned_is_arr[sorted_idx_is] aligned_an_arr = aligned_an_arr[sorted_idx_an] # 执行归一化 norm_arr = aligned_is_arr[:, 1] / aligned_an_arr[:, 1] norm_list = norm_arr.tolist()
该方法无需引入额外库,完全基于Numpy操作,适合已在Numpy生态中工作的场景。
内容的提问来源于stack exchange,提问作者Bob Challen
相关产品推荐
相关产品推荐

