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
相关产品推荐
相关产品推荐

