如何使用格式不正确的文件读取csv



我有一个文本文件作为示例如下:

col A,col B,col C,col D,col E
val A1,val B1,val C1,val D1,val E1, val E2, val E3
val A2,val B2, val C2,val D2, val E4

请注意,列E中的一些值具有多个值"例如val E1、val E2、val E3

当我使用df = pd.read_csv(r'path/text_file.txt', sep="t")时,它读取为一列,而不是多列,如下所示:

列A、列B、列C、列D、列E
val A1、val B1、val C1、val D1、val E1、val E2、val E3
val A2、val B2、val C2、val D2、val E4
  • 在31201行的文件中,此解决方案比此解决方案快80倍
  • 该文件不是格式正确的csv文件。属于1列的多个逗号分隔的值应使用双引号,如"val E1, val E2, val E3"

修复数据格式

  1. .open文件并用列表理解进行修复
  2. for l in f遍历每行字符串
  3. 使用row := l.strip().split(',')将每一行拆分为一个列表,该列表使用赋值表达式(:=)并需要python >= 3.8
    • 底部有一个不带:=的选项
  4. 固定行
    • [','.join(row[4:])]加入任何>=将索引4转换为列表中的单个字符串,即将它们组合回前4个值的列表row[:4]
  5. 加载到数据帧中
import pandas as pd
with open('test.txt') as f:
rows = [row[:4] + [','.join(row[4:])] for l in f if (row := l.strip().split(',')) is not None] 
df = pd.DataFrame(rows[1:], columns=rows[0])
# display(df)
col A   col B    col C   col D                   col E
0  val A1  val B1   val C1  val D1  val E1, val E2, val E3
1  val A2  val B2   val C2  val D2                  val E4
df.to_csv('test.txt', index=False)
# properly formatted csv
col A,col B,col C,col D,col E
val A1,val B1,val C1,val D1,"val E1, val E2, val E3"
val A2,val B2, val C2,val D2, val E4

%%timeit比较

  • 在具有31201行的test.txt上执行
%%timeit
with open('test.txt') as f:
rows = [row[:4] + [','.join(row[4:])] for l in f if (row := l.strip().split(',')) is not None]
df = pd.DataFrame(rows[1:], columns=rows[0])
[result]: 50.8 ms ± 3.19 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%%timeit
df=pd.read_csv('test.txt', header=None, skiprows=1, engine='python')
cols=pd.read_csv('test.txt',skipfooter=len(df)).columns
df[4]=df.loc[:,4:].agg(lambda x:','.join(x.dropna()),1)
df=df.loc[:,:4]
df.columns=cols
[result]: 4.04 s ± 30 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

不带赋值表达式的选项

54.3 ms ± 1.39 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)%%timeit
with open('test.txt') as f:
rows = list()
for l in f:
row = l.strip().split(',')
row = row[:4] + [','.join(row[4:])]
rows.append(row)

df = pd.DataFrame(rows[1:], columns=rows[0])

您可以尝试格式化文件:

首先读取没有标题的csv文件,然后在csv文件中获取列名称,然后连接第4列的单元格值:通过',',然后使用iloc获取第4列上的df,最后设置列名称并将文件保存到csv

df=pd.read_csv(r'path/text_file.txt',header=None,skiprows=1)
cols=pd.read_csv(r'path/text_file.txt',skipfooter=len(df)).columns
df[4]=df.loc[:,4:].agg(lambda x:','.join(x.dropna()),1)
df=df.loc[:,:4]
df.columns=cols
df.to_csv(r'path/text_file.txt',index=False)

格式化后csv文件的输出:

col A,col B,col C,col D,col E
val A1,val B1,val C1,val D1,"val E1, val E2, val E3"
val A2,val B2, val C2,val D2, val E4

相关内容

  • 没有找到相关文章

最新更新