如何用Pandas apply()从单列生成两列?报错及NaN异常求助
正确使用apply()生成多列的方法
问题分析
你之前的两种方法都存在问题:
- 第一种方法错误使用了
result_type='expand',这个参数属于DataFrame的apply方法,Series的apply不支持该参数;同时lambda表达式返回了三元组(不符合你要生成两列的需求)。 - 第二种方法错误地用
str.split()处理元组类型数据,gene_isMANE列存储的是Python元组,不是字符串,因此无法通过字符串分割提取元素。
方法一:直接用Series.apply返回二元组并赋值给多列
这是最直接的方式,当apply返回长度一致的二元组时,Pandas会自动将其展开为两列:
import pandas as pd exonbed = pd.DataFrame(['NM_1234','NM_123456','NM_1234567'], columns=['trid']) gene_trid_reverse = {'NM_1234':'gene1','NM_123456':'gene2'} # 直接生成两列 exonbed[['gene', 'isMANE']] = exonbed['trid'].apply( lambda x: (gene_trid_reverse[x], 'MANE') if x in gene_trid_reverse else (x, 'NO MANE') ).tolist()
这里用
.tolist()确保Pandas能正确识别元组序列为多列数据,部分Pandas版本可省略,但加上兼容性更好。
运行后结果:
trid gene isMANE 0 NM_1234 gene1 MANE 1 NM_123456 gene2 MANE 2 NM_1234567 NM_1234567 NO MANE
方法二:先生成元组列,再提取元素
如果你想保留中间的元组列,正确的提取方式是用apply直接取元组的索引,而非字符串分割:
exonbed['gene_isMANE'] = exonbed['trid'].apply( lambda x: (gene_trid_reverse[x], 'MANE') if x in gene_trid_reverse else (x, 'NO MANE') ) # 从元组中提取元素 exonbed['gene'] = exonbed['gene_isMANE'].apply(lambda x: x[0]) exonbed['isMANE'] = exonbed['gene_isMANE'].apply(lambda x: x[1])
运行后同样能得到正确的非NaN结果。
内容的提问来源于stack exchange,提问作者tan qiang
相关产品推荐
相关产品推荐

