如何基于多条件为DataFrame新增列并填充指定非NaN有效值
解决方法
首先,你的核心问题在于没有处理EX行需要继承对应GEN行的gs值这个逻辑,而且直接用row['gs'] != NaN的判断是错误的(在Python中,NaN和任何值比较都会返回False,必须用pd.isna()来判断)。
下面是具体的实现步骤,完全符合你的需求:
1. 先构造示例DataFrame(方便测试)
import pandas as pd import numpy as np data = { 'col1': ['chr1']*6, 'col2': ['HAS']*6, 'col3': ['GEN', 'TRANS', 'EX', 'GEN', 'EX', 'EX'], 'start': [11869, 11869, 11869, 12613, 13221, 12010], 'end': [14409, 14409, 12227, 12721, 14409, 12057], 'gs': ['DDX', pd.NA, pd.NA, 'FXBZ', pd.NA, pd.NA] } df = pd.DataFrame(data)
2. 生成目标列col7
我们可以通过临时列+向前填充的方式,让EX行自动继承最近GEN行的gs值,再根据col3的条件赋值:
# 第一步:只保留GEN行的gs值,其他行设为NaN,然后向前填充(让后续的EX行拿到最近GEN的gs) df['temp_gs'] = df['gs'].where(df['col3'] == 'GEN').ffill() # 第二步:根据col3的条件设置col7 df['col7'] = np.where( df['col3'].isin(['GEN', 'EX']), # 当col3是GEN或EX时 df['temp_gs'], # 使用填充后的gs值 'no' # 其他情况填"no" ) # 可选:删除临时列 df.drop('temp_gs', axis=1, inplace=True)
执行后得到的结果完全符合你的期望:
col1 col2 col3 start end gs col7 0 chr1 HAS GEN 11869 14409 DDX DDX 1 chr1 HAS TRANS 11869 14409 <NA> no 2 chr1 HAS EX 11869 12227 <NA> DDX 3 chr1 HAS GEN 12613 12721 FXBZ FXBZ 4 chr1 HAS EX 13221 14409 <NA> FXBZ 5 chr1 HAS EX 12010 12057 <NA> FXBZ
为什么你的原方法失败?
- NaN判断错误:不能直接用
row['gs'] != NaN,必须用pd.isna(row['gs'])来检测缺失值,因为NaN的特性是和任何值比较都返回False。 - 逻辑缺失:EX行本身的
gs是NaN,你需要的是对应GEN行的gs值,而不是当前行的gs,所以单靠行级的lambda判断无法实现,必须通过向前填充来关联GEN和EX行。 - 条件覆盖不全:你的原lambda只判断了
col3 == "EX" and row['gs'] !=NaN,但GEN行的情况也需要保留自身的gs值,同时TRANS等其他情况才填"no"。
内容的提问来源于stack exchange,提问作者ARJ
相关产品推荐
相关产品推荐

