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

Python/Pandas按行内指定位置拆分字符串列的技术实现问题

按每行指定规则拆分Pandas DataFrame的字符串列

有一个Pandas DataFrame,包含campaign_name列,内容是按规则生成的字符串;同时还有separator(分隔符)、SKU、CAMPAIGN、GOAL、FORMAT列,记录每行字符串的分隔符,以及各信息对应的拆分后位置。比如第一行里,字符串用下划线分隔,SKU对应拆分后的第0位,CAMPAIGN对应第1位,GOAL对应第2位。现在要按每行指定的位置拆分campaign_name列,但当前代码无法实现需求。

示例DataFrame

results = pd.DataFrame([{'data': '2022-01-01' , 'canal': 'Facebook/Instagram' , 'campaign_name': 'SKU098_COMMERCIALCAMPAIGN_VIEW' , 'Cost': 1.5 , 'separator': '_' , 'SKU': 0, 'CAMPAIGN': 1, 'GOAL': 2, 'FORMAT': 100},
                        {'data': '2019-01-01' , 'canal': 'Facebook/Instagram' , 'campaign_name': 'NEWYEAR_REACH_SKU4354' , 'Cost': 0.4 , 'separator': '_' , 'SKU': 2, 'CAMPAIGN': 0, 'GOAL': 1, 'FORMAT': 100},
                        {'data': '2022-01-09' , 'canal': 'Facebook/Instagram' , 'campaign_name': 'VIDEO_REACH_SKU4354' , 'Cost': 2.1 , 'separator': '_' , 'SKU': 2, 'CAMPAIGN': 100, 'GOAL': 1, 'FORMAT': 0},
                        {'data': '2022-08-20' , 'canal': 'Facebook/Instagram' , 'campaign_name': 'INTERATIONS/SKU2134/CHRISTMAS' , 'Cost': 1.2 , 'separator': '/' , 'SKU': 1, 'CAMPAIGN': 2, 'GOAL': 0, 'FORMAT': 100}
                       ])
print(results)

当前尝试的代码

results['SKU_2'] = results['campaign_name'].str.split(results['separator']).str[results['SKU']]

期望结果

data               canal                   campaign_name  Cost separator      SKU         CAMPAIGN               GOAL        FORMAT  
0  2022-01-01  Facebook/Instagram  SKU098_COMMERCIALCAMPAIGN_VIEW   1.5          _    SKU098      COMMERCIALCAMPAIGN     VIEW        NaN  
1  2019-01-01  Facebook/Instagram           NEWYEAR_REACH_SKU4354   0.4          _    SKU4354     NEWYEAR                REACH       NaN 
2  2022-01-09  Facebook/Instagram             VIDEO_REACH_SKU4354   2.1          _    SKU4354     NaN                    REACH       VIDEO 
3  2022-08-20  Facebook/Instagram   INTERATIONS/SKU2134/CHRISTMAS   1.2          /    SKU2134     CHRISTMAS              INTERATIONS NaN 

解决方案

原来的代码行不通是因为str.split没法直接接收Series作为分隔符参数,而且str[]也不能按行取不同的索引值。这里提供两种可行的方法:

方法一:用apply逐行处理

这是最直观的方式,逐行拆分字符串并提取对应位置的内容:

import pandas as pd

def process_row(row):
    # 按当前行的分隔符拆分字符串
    parts = row['campaign_name'].split(row['separator'])
    # 提取各字段,索引超出范围则设为NaN
    row['SKU'] = parts[row['SKU']] if row['SKU'] < len(parts) else pd.NA
    row['CAMPAIGN'] = parts[row['CAMPAIGN']] if row['CAMPAIGN'] < len(parts) else pd.NA
    row['GOAL'] = parts[row['GOAL']] if row['GOAL'] < len(parts) else pd.NA
    row['FORMAT'] = parts[row['FORMAT']] if row['FORMAT'] < len(parts) else pd.NA
    return row

# 应用到每行
results = results.apply(process_row, axis=1)
print(results)

方法二:预拆分后批量提取

先拆分所有行的字符串,再批量匹配索引取值,大数据量下效率稍高:

import pandas as pd

# 先拆分所有行的campaign_name,得到包含拆分后列表的Series
split_parts = results.apply(lambda x: x['campaign_name'].split(x['separator']), axis=1)

# 需要处理的字段列表
fields = ['SKU', 'CAMPAIGN', 'GOAL', 'FORMAT']

# 逐个字段提取对应位置的内容
for field in fields:
    results[field] = [
        parts[idx] if idx < len(parts) else pd.NA 
        for parts, idx in zip(split_parts, results[field])
    ]

print(results)

两种方法都能得到符合期望的结果,核心逻辑都是确保每行的分隔符和索引一一对应,同时处理索引超出范围的情况(比如值为100时返回NaN)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 23:06:24