簡體   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