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

Python处理CSV:提取子串后无法对应原行输出问题求助

问题描述

我有如下格式的CSV文件:

transaction,count,id,type,subtype,descripcion_d
220402  09290660100100D811  5711  4210030031652691,2,,,,
220402  09290660100100D811  5711  4210030031652691,5,,,,
220402  09290660100100D811  5711  5063030031652691,1,,,,
220402  09290660100100D811  5711  5063012331652691,2,,,,
220402  09290660100100D811  7911  5579100340131388,1,,,,
220525  09290660100100D811  7911  5579125487855558,1,,,,
220525  09290660100100D811  7471  5579112255788869,1,,,,
220525  09290660100100D811  7471  5579134567651389,1,,,,

删除不需要的列后,仅保留transaction列:

220402  09290660100100D811  5711  4210030031652691
220402  09290660100100D811  5711  4210030031652691
220402  09290660100100D811  5711  5063030031652691
220402  09290660100100D811  5711  5063012331652691
220402  09290660100100D811  7911  5579100340131388
220525  09290660100100D811  7911  5579125487855558
220525  09290660100100D811  7471  5579112255788869
220525  09290660100100D811  7471  5579134567651389

需要实现两个操作:

  • 提取transaction列前6位数字,格式化为date列(如220402转为20220402);
  • 提取transaction列中以5579开头的16位数字作为Serial列。

编写的Python代码如下:

import csv
import pandas as pd 

df = pd.read_csv('transactions.csv')
df.head(10)
cadena=df["transaction"]
x="5579"
df["Serial"]=""
df["date"]=""
        
   
for i in cadena:
if x in i:
    pin=i.find(x)
    serie=i[pin:]
    longitud=len(serie)
    if longitud==16:
        df.loc[i,"Serial"]=serie
        df.to_csv("test.csv", index=False, na_rep="")
       
        for i in cadena:
            if int(i[0:2])==22:
                agno=(i[0:2])
                mes=i[2:4]
                dia=i[4:6]
                date="20"+agno+mes+dia
                df.loc[i,"date"]=date
                df.to_csv("test.csv", index=False, na_rep="")

运行后Serial和date列内容与原transaction行错位,需要修改代码让提取的内容对应到原行。


问题分析与修正方案

原代码的核心问题是用transaction的字符串值作为行索引去定位(df.loc[i,"Serial"]中的i是字符串内容,不是行号),而Pandas的loc默认按索引匹配,当没有对应的字符串索引时就会出现错位或新增行的情况。另外代码嵌套循环逻辑混乱,每次循环都写入CSV也会导致重复操作。

以下是修正后的代码:

import pandas as pd 

# 直接读取需要的transaction列,无需手动提前删除其他列
df = pd.read_csv('transactions.csv', usecols=['transaction'])

# 1. 生成date列:取transaction前6位,拼接20前缀
df['date'] = '20' + df['transaction'].str[:6]

# 2. 生成Serial列:提取以5579开头的16位纯数字串
def extract_serial(s):
    start_idx = s.find('5579')
    if start_idx != -1:
        candidate = s[start_idx:start_idx+16]
        # 验证是否为16位纯数字
        if len(candidate) == 16 and candidate.isdigit():
            return candidate
    return ''

df['Serial'] = df['transaction'].apply(extract_serial)

# 最后统一写入CSV,避免重复操作
df.to_csv("test.csv", index=False, na_rep="")

关键修改点

  • 改用Pandas的向量化操作(str[:6])和apply方法,避免遍历字符串值定位行,确保每行对应正确;
  • 提取Serial时增加isdigit()验证,确保提取的是纯数字的16位串;
  • 把CSV写入操作放在最后,避免多次重复写入;
  • 使用usecols参数直接读取目标列,简化预处理步骤。

执行后,date和Serial列会准确对应到原transaction的每一行,不会出现错位。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 12:03:37