繁体   English   中英

Python:以任意数量的制表符作为分隔符读取csv文件

[英]Python: Read csv file with an arbitrary number of tabs as delimiter

我通过在不同值之间使用一个或多个选项卡,很好地格式化了所有列格式的csv文件。

我知道可以将单个选项卡与csv.register_dialect("tab_delimiter", delimiter="\\t")用作分隔符。 但这仅适用于值之间的一个制表符。 我想处理保持其格式的文件,即不删除重复的选项卡。 每个字段(行,列)都包含一个值。

是否可以使用多个1+制表符作为定界符或忽略其他制表符而不影响一行中值的编号? row[1]应该是第二个值,而与row[0]之间的制表符数量无关。

##Sample.txt
##ID    name    Age
##1 11  111
##2     22  222


import pandas as pd
df=pd.read_csv('Sample.txt' ,sep=r'\t+')
print df

假设永远不会有空字段,您可以使用生成器从传入的CSV文件中删除重复项,然后照常使用csv模块:

import csv

def de_dup(f, delimiter='\t'):
    for line in f:
        yield delimiter.join(field for field in line.split(delimiter) if field)

with open('data.csv') as f:
    for row in csv.reader(de_dup(f), delimiter='\t'):
        print(row)

另一种方法是在生成器中使用re.sub()

import re

def de_dup(f, delimiter='\t'):
    for line in f:
        yield re.sub(r'{}{{2,}}'.format(delimiter), delimiter, line)

但这仍然具有所有字段必须包含值的限制。

对于我来说,处理多个选项卡最方便的方法是使用一个附加函数,该函数接受行并删除由一行中的多个选项卡创建的空值/字段。 这不会影响csv文件的格式,我可以使用row[1]访问该行中的第二个值-即使前面有多个选项卡也是如此。

def remove_empty(line):
    result = []
    for i in range(len(line)):
        if line[i] != "":
            result.append(line[i])
    return result

在读取文件并处理值的代码中:

for row in reader:
    row = remove_empty(row)
    **continue processing normally**

我认为该解决方案与mhawke的解决方案相似,但是使用他的解决方案,我无法像以前一样使用row[i]访问相同的值(即,每个值之间只有一个定界符)。

或者,对于任何类型的重复分隔符,完全通用的解决方案是用单个分隔符递归替换每个多个分隔符,然后写入新文件(尽管对于千兆字节大小的CSV文件来说这很慢):

def replaceMultipleSeparators( fileName, oldSeparator, newSeparator ):
  linesOfCsvInputFile = open( fileName, encoding='utf-8', mode='r' ).readlines()

  csvNewFileName = fileName + ".new"
  print('Writing:   %s replacing %s with %s' % ( csvNewFileName, oldSeparator, newSeparator ) , end='' )
  outputFileStream = open( newFileName, 'w' )
  for line in linesOfCsvInputFile:
    newLine = line.rstrip()
    processedLine = ""
    while newLine != processedLine:
      processedLine = newLine
      newLine = processedLine.replace( oldSeparator + oldSeparator, oldSeparator )
    newLine = newLine.replace( oldSeparator, newSeparator )
    outputFileStream.write( newLine + '\n' )
  outputFileStream.close()

如果运行以下命令,给定的输入testFile.csv将生成带有TAB的PIPE替换的testFile.csv.new:

replaceMultipleSeparators( 'testFile.csv', '\t', '|' )

有时,对于某些Microsoft在美国生成的CSV文件,您需要将“ utf-8”编码替换为“ latin-1”。 有关此问题,请参阅与0xe4读取相关的错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM