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

Pandas:基于特定值选择性拼接列的技术问题求助

Pandas序列号拼接:高效向量化解决方案

问题回顾

数据集包含sn1至sn13列,其中前11列(列名存于serialname_list)为序列号的ASCII码,需完成:

  1. 将ASCII码转为字符
  2. 按两种格式拼接序列号:
    • 常规格式:XXX-XXXX-XXX(sn4不为'A'时)
    • 特殊格式:XXXA-XXX-XXX(sn4为'A'时,A固定在第4位)
  3. 结果存入serial字段,移除原sn列

原代码存在两个核心问题:

  • 两次赋值serial字段,导致不符合条件的行被覆盖为NaN
  • 逐行apply效率低下,未利用Pandas向量化特性

问题根源

原代码中df['serial'] = df[df['sn4']=='A'].apply(...)仅给符合条件的行赋值,其他行留空;第二次赋值df['serial'] = df[df['sn4']!='A'].apply(...)会覆盖第一次的结果,最终只有第二次条件匹配的行有值,其余为NaN。

优化方案(向量化实现)

利用Pandas字符串操作和np.where实现全量向量化处理,彻底避免逐行循环:

步骤1:ASCII转字符

用applymap直接对所有元素执行chr转换,比逐列map更简洁:

df_serial = df[serialname_list].applymap(chr)

步骤2:构造完整字符串并按格式拆分拼接

先将每行的字符拼接成完整字符串,再按两种格式截取并添加分隔符:

# 拼接每行的所有字符为完整字符串
df_serial['full_str'] = df_serial.agg(''.join, axis=1)

# 生成常规格式序列号:XXX-XXXX-XXX
df_serial['normal_serial'] = (
    df_serial['full_str'].str[:3] + '-' +
    df_serial['full_str'].str[3:7] + '-' +
    df_serial['full_str'].str[7:10]
)

# 生成特殊格式序列号:XXXA-XXX-XXX
df_serial['long_serial'] = (
    df_serial['full_str'].str[:4] + '-' +
    df_serial['full_str'].str[4:7] + '-' +
    df_serial['full_str'].str[7:10]
)

步骤3:根据sn4值选择对应格式

用np.where一次性完成赋值,完全避免覆盖问题:

import numpy as np

df_serial['serial'] = np.where(
    df_serial['sn4'] == 'A',
    df_serial['long_serial'],
    df_serial['normal_serial']
)

步骤4:清理冗余列

保留serial字段,移除原sn列和中间临时列:

result = df_serial.drop(columns=serialname_list + ['full_str', 'normal_serial', 'long_serial'])

完整优化代码

import numpy as np
import pandas as pd

def convertserial(df):
    # 1. ASCII转字符
    df_serial = df[serialname_list].applymap(chr)
    
    # 2. 拼接完整字符串并生成两种格式的序列号
    df_serial['full_str'] = df_serial.agg(''.join, axis=1)
    
    # 常规格式:XXX-XXXX-XXX
    df_serial['normal_serial'] = (
        df_serial['full_str'].str[:3] + '-' +
        df_serial['full_str'].str[3:7] + '-' +
        df_serial['full_str'].str[7:10]
    )
    
    # 特殊格式:XXXA-XXX-XXX
    df_serial['long_serial'] = (
        df_serial['full_str'].str[:4] + '-' +
        df_serial['full_str'].str[4:7] + '-' +
        df_serial['full_str'].str[7:10]
    )
    
    # 3. 根据sn4选择对应格式
    df_serial['serial'] = np.where(
        df_serial['sn4'] == 'A',
        df_serial['long_serial'],
        df_serial['normal_serial']
    )
    
    # 4. 清理冗余列
    return df_serial.drop(columns=serialname_list + ['full_str', 'normal_serial', 'long_serial'])

关键优势

  • 效率提升:全向量化操作避免逐行循环,处理大数据集时性能远超apply(axis=1)
  • 无值覆盖:一次性赋值所有行,不会出现NaN覆盖问题
  • 代码简洁:逻辑清晰,易于维护和扩展

内容的提问来源于stack exchange,提问作者user2059972

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 09:06:02