You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为含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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 19:10:32