为含dx前缀列的DataFrame生成primary列:按指定规则赋值
解决方案
针对需求,这里提供两种pandas实现方式,分别适合小数据量的直观写法和大数据量的高效矢量化写法:
方法一:逐行处理(直观易懂)
先构造示例数据,再通过自定义函数逐行判断:
import pandas as pd import numpy as np # 构造示例DataFrame data = { 'dx1': ['I629', 'S065', 'I629', 'I629'], 'dx2': [np.nan, np.nan, 'S066', 'I629'], 'dx3': [np.nan, np.nan, np.nan, np.nan], 'dx4': [np.nan, np.nan, np.nan, np.nan], 'dx5': [np.nan, np.nan, np.nan, np.nan] } df = pd.DataFrame(data) # 筛选所有dx前缀的列 dx_cols = df.filter(like='dx').columns def get_primary(row): # 提取当前行非空的dx值 dx_vals = row[dx_cols].dropna() # 若所有非空值都是"I629",返回Unspecified if dx_vals.eq('I629').all(): return 'Unspecified' # 否则返回第一个非"I629"的值 return dx_vals[dx_vals != 'I629'].iloc[0] # 新增primary列 df['primary'] = df.apply(get_primary, axis=1)
运行后得到的结果和示例完全一致:
dx1 dx2 dx3 dx4 dx5 primary 0 I629 NaN NaN NaN NaN Unspecified 1 S065 NaN NaN NaN NaN S065 2 I629 S066 NaN NaN NaN S066 3 I629 I629 NaN NaN NaN Unspecified
方法二:矢量化处理(高效适合大数据)
避免逐行循环,用pandas的矢量化操作提升效率:
import pandas as pd import numpy as np # 构造示例DataFrame(同上) data = { 'dx1': ['I629', 'S065', 'I629', 'I629'], 'dx2': [np.nan, np.nan, 'S066', 'I629'], 'dx3': [np.nan, np.nan, np.nan, np.nan], 'dx4': [np.nan, np.nan, np.nan, np.nan], 'dx5': [np.nan, np.nan, np.nan, np.nan] } df = pd.DataFrame(data) # 提取dx前缀列 dx_df = df.filter(like='dx') # 将"I629"和空值替换为NaN,保留有效目标值 masked_dx = dx_df.mask((dx_df == 'I629') | dx_df.isna()) # 按行取第一个非NaN的有效目标值 first_valid = masked_dx.bfill(axis=1).iloc[:, 0] # 空值替换为Unspecified,得到最终primary列 df['primary'] = first_valid.fillna('Unspecified')
这个方法的逻辑是:先把不需要的("I629"和NA)标记为NaN,然后按行从后往前填充(bfill),取第一列就是第一个有效非"I629"的值;如果整行都是NaN,说明所有dx列都是"I629"或NA,填充为"Unspecified"。
内容的提问来源于stack exchange,提问作者ltong
相关产品推荐
相关产品推荐

