如何基于Alias列子串匹配合并不同大小的DataFrame
实现DataFrame间的Alias最优子串匹配并关联MiRBase_ID
问题说明
现有两个DataFrame:
df1(包含Alias和seq_RNA列)
Alias seq_RNA Hsa-Mir-133-P2-v1-5p AGCTGGTAAAATGGAACCAAATC Hsa-Mir-143-P1-v2-3p TTGGTCCCCTTCAACCAGCTGT Hsa-Mir-183-P1-v1-3p TTTGGTCCCCTTCAACCAGCTGT Hsa-Mir-490-3p CAACCTGGAGGACTCCATGCTGT Hsa-Mir-499-5p TTAAGACTTGCAGTGATGTTTA Hsa-Mir-163-P2-v2-3p TTGGTCCCCTTCAACCAGCTA Hsa-Mir-122-as-5p TTTAGTGTGATAATGGCGTTTG Hsa-Mir-1-P1-5p ACATACTTCTTTATATGCCCATA
df2(包含Alias和MiRBase_ID列)
Alias MiRBase_ID Hsa-Mir-4-P1 hsa-let-133 Hsa-Let-7-P1c hsa-let-7c Hsa-Let-7-P1d hsa-let-7a-2 Hsa-Mir-183-P1 hsa-let-183 Hsa-Mir-122-as hsa-let-122 Hsa-Let-7-P2a3 hsa-let-7f-2
需要生成df3,规则为:
- 当df1的Alias与df2的Alias存在子串匹配时,选取最长匹配的子串对应的MiRBase_ID
- 无匹配时填充
na
预期结果df3:
Alias seq_RNA MiRBase_ID Hsa-Mir-133-P2-v1-5p AGCTGGTAAAATGGAACCAAATC na Hsa-Mir-143-P1-v2-3p TTGGTCCCCTTCAACCAGCTGT na Hsa-Mir-183-P1-v1-3p TTTGGTCCCCTTCAACCAGCTGT hsa-let-183 Hsa-Mir-490-3p CAACCTGGAGGACTCCATGCTGT na Hsa-Mir-499-5p TTAAGACTTGCAGTGATGTTTA na Hsa-Mir-163-P2-v2-3p TTGGTCCCCTTCAACCAGCTA na Hsa-Mir-122-as-5p TTTAGTGTGATAATGGCGTTTG hsa-let-122 Hsa-Mir-1-P1-5p ACATACTTCTTTATATGCCCATA na
解决方案
使用Python的pandas库实现,核心是为每个df1的Alias找到df2中最长匹配的Alias子串,步骤如下:
- 导入pandas并构造示例DataFrame
import pandas as pd # 构造df1 df1_data = { 'Alias': [ 'Hsa-Mir-133-P2-v1-5p', 'Hsa-Mir-143-P1-v2-3p', 'Hsa-Mir-183-P1-v1-3p', 'Hsa-Mir-490-3p', 'Hsa-Mir-499-5p', 'Hsa-Mir-163-P2-v2-3p', 'Hsa-Mir-122-as-5p', 'Hsa-Mir-1-P1-5p' ], 'seq_RNA': [ 'AGCTGGTAAAATGGAACCAAATC', 'TTGGTCCCCTTCAACCAGCTGT', 'TTTGGTCCCCTTCAACCAGCTGT', 'CAACCTGGAGGACTCCATGCTGT', 'TTAAGACTTGCAGTGATGTTTA', 'TTGGTCCCCTTCAACCAGCTA', 'TTTAGTGTGATAATGGCGTTTG', 'ACATACTTCTTTATATGCCCATA' ] } df1 = pd.DataFrame(df1_data) # 构造df2 df2_data = { 'Alias': [ 'Hsa-Mir-4-P1', 'Hsa-Let-7-P1c', 'Hsa-Let-7-P1d', 'Hsa-Mir-183-P1', 'Hsa-Mir-122-as', 'Hsa-Let-7-P2a3' ], 'MiRBase_ID': [ 'hsa-let-133', 'hsa-let-7c', 'hsa-let-7a-2', 'hsa-let-183', 'hsa-let-122', 'hsa-let-7f-2' ] } df2 = pd.DataFrame(df2_data)
- 定义匹配函数,寻找最长子串匹配
def find_best_match(alias, df2): # 筛选出是当前alias子串的df2 Alias matches = df2[df2['Alias'].apply(lambda x: x in alias)] if matches.empty: return pd.NA # 按子串长度降序排序,取最长的那个 longest_match = matches.loc[matches['Alias'].str.len().idxmax()] return longest_match['MiRBase_ID'] # 应用函数到df1的Alias列 df1['MiRBase_ID'] = df1['Alias'].apply(lambda x: find_best_match(x, df2)) # 得到df3 df3 = df1
- 查看结果
print(df3)
输出结果与预期一致。
说明
- 该方案通过遍历df1的每个Alias,筛选出所有是其子串的df2 Alias,再选择最长的匹配项,确保是最优匹配
- 处理了无匹配的情况,自动填充
pd.NA(对应示例中的na) - 不受两个DataFrame的行数和顺序影响
内容的提问来源于stack exchange,提问作者pino
相关产品推荐
相关产品推荐

