#python #csv #tabs
#python #csv #вкладки
Вопрос:
Мой csv-файл отформатирован так, что все столбцы выровнены с помощью одной или нескольких вкладок между разными значениями.
Я знаю, что можно использовать одну вкладку в качестве разделителя с csv.register_dialect("tab_delimiter", delimiter="t")
. Но это работает только с одной табуляцией между значениями. Я хотел бы обработать файл, сохранив его формат, т. Е. не удаляя дублирующиеся вкладки. Каждое поле (строка, столбец) содержит значение.
Возможно ли использовать количество вкладок 1 в качестве разделителя или игнорировать дополнительные вкладки, не влияя на нумерацию значений в строке? row[1]
должно быть вторым значением, не зависящим от того, сколько вкладок находится между ними row[0]
.
Комментарии:
1. Читая документы, я понял, что вы можете использовать только один символ в качестве разделителя. Я думаю, ваш лучший вариант — предварительно обработать файл, чтобы удалить дублирующиеся вкладки.
2. При условии, что каждая строка содержит данные для каждого столбца, просто с различным количеством вкладок в качестве разделителей, вы можете просто обработать это с пониманием списка,
separated = [item for item in row if item]
гдеrow
находится строка в вашемcsv.reader()
. Если в некоторых строках есть пустые записи, то я не вижу никакого способа добиться этого.
Ответ №1:
##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
Комментарии:
1. Есть ли способ заставить это работать с
csv
вместоpandas
?
Ответ №2:
Предполагая, что пустых полей никогда не будет, вы можете использовать генератор для удаления дубликатов из входящего 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)
но это все еще имеет ограничение, заключающееся в том, что все поля должны содержать значение.
Ответ №3:
Для меня наиболее удобным способом работы с несколькими вкладками было использование дополнительной функции, которая принимает строку и удаляет пустые значения / поля, созданные несколькими вкладками подряд. Это не влияет на форматирование 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]
, что и раньше (т. Е. только с одним разделителем между каждым значением).
Ответ №4:
Или полностью общим решением для любого типа повторяющихся разделителей является рекурсивная замена каждого множественного разделителя одним разделителем и запись в новый файл (хотя это медленно для файлов 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 будет генерироваться testFile.csv.new с вкладками, замененными каналами, если вы запустите:
replaceMultipleSeparators( 'testFile.csv', 't', '|' )
Иногда вам потребуется заменить кодировку ‘utf-8’ на ‘latin-1’ для некоторых CSV-файлов, созданных Microsoft US. Смотрите ошибки, связанные с чтением 0xe4 для этой проблемы.