Python实现列表元素与DataFrame列部分匹配并提取对应列值
解决方法
方法1:完善你的循环思路
你原来的循环逻辑没问题,但直接判断i in genes_df.iloc[:,0]匹配不到带后缀的ID,改成用str.startswith判断前缀即可:
import pandas as pd ENSEMBL_IDs = ['ENSG00000040608', 'ENSG00000070371', 'ENSG00000070413'] genes_list = (['ENSG00000040608.28', 'RTN4R'], ['ENSG00000070371.91', 'CLTCL1'], ['ENSG00000070413.17', 'DGCR2']) genes_df = pd.DataFrame(genes_list) genenames = [] for ens_id in ENSEMBL_IDs: # 筛选第0列中以当前ID开头的行 match_row = genes_df[genes_df.iloc[:,0].str.startswith(ens_id)] # 提取对应基因名(题目保证存在,直接取第一行) genenames.append(match_row.iloc[0, 1]) print(genenames) # 输出: ['RTN4R', 'CLTCL1', 'DGCR2']
方法2:字典映射(高效处理长列表)
如果你的ENSEMBL_IDs元素很多,用字典映射效率更高,因为字典查找是常数时间:
import pandas as pd ENSEMBL_IDs = ['ENSG00000040608', 'ENSG00000070371', 'ENSG00000070413'] genes_list = (['ENSG00000040608.28', 'RTN4R'], ['ENSG00000070371.91', 'CLTCL1'], ['ENSG00000070413.17', 'DGCR2']) genes_df = pd.DataFrame(genes_list) # 生成"无后缀ID:基因名"的字典 id_gene_map = dict(zip( genes_df.iloc[:,0].str.split('.').str[0], # 去掉第0列的后缀 genes_df.iloc[:,1] )) # 批量提取基因名 genenames = [id_gene_map[ens_id] for ens_id in ENSEMBL_IDs] print(genenames) # 输出: ['RTN4R', 'CLTCL1', 'DGCR2']
方法3:pandas矢量化筛选(适合复杂场景)
如果需要保留DataFrame的操作逻辑,可以新增无后缀ID列后筛选:
import pandas as pd ENSEMBL_IDs = ['ENSG00000040608', 'ENSG00000070371', 'ENSG00000070413'] genes_list = (['ENSG00000040608.28', 'RTN4R'], ['ENSG00000070371.91', 'CLTCL1'], ['ENSG00000070413.17', 'DGCR2']) genes_df = pd.DataFrame(genes_list) # 新增列存储无后缀的ENSEMBL ID genes_df['clean_ens_id'] = genes_df.iloc[:,0].str.split('.').str[0] # 按ENSEMBL_IDs的顺序匹配并提取基因名 genenames = genes_df.set_index('clean_ens_id').reindex(ENSEMBL_IDs).iloc[:,1].tolist() print(genenames) # 输出: ['RTN4R', 'CLTCL1', 'DGCR2']
内容的提问来源于stack exchange,提问作者tom
相关产品推荐
相关产品推荐

