Processamento de Ficheiros de texto com Python

estou a tentar analisar uma série de ficheiros de texto e gravá-los como ficheiros CSV usando Python (2.7.3). Todos os arquivos de texto têm um cabeçalho de 4 linhas que precisa ser removido. As linhas de dados têm vários delimitadores, incluindo " (quote), - (traço), : coluna, e espaço em branco. Eu achei uma dor codificá-lo em C++ com todos esses diferentes delimitadores, então eu decidi experimentá-lo em Python ouvir que é relativamente mais fácil de fazer em comparação com C/C++.

Escrevi um código para testá-lo para um único. linha de dados e funciona, no entanto, eu não poderia fazê-lo funcionar para o arquivo real. Para analisar uma única linha eu estava usando o objeto de texto e método de "substituir". Parece que a minha implementação atual lê o arquivo de texto como uma lista, e não há nenhum método de substituição para o objeto da lista.

Sendo um novato em Python, fiquei preso nesta altura. Qualquer entrada seria apreciada!

Obrigado!

# function for parsing the data
def data_parser(text, dic):
for i, j in dic.iteritems():
    text = text.replace(i,j)
return text

# open input/output files

inputfile = open('test.dat')
outputfile = open('test.csv', 'w')

my_text = inputfile.readlines()[4:] #reads to whole text file, skipping first 4 lines


# sample text string, just for demonstration to let you know how the data looks like
# my_text = '"2012-06-23 03:09:13.23",4323584,-1.911224,-0.4657288,-0.1166382,-0.24823,0.256485,"NAN",-0.3489428,-0.130449,-0.2440527,-0.2942413,0.04944348,0.4337797,-1.105218,-1.201882,-0.5962594,-0.586636'

# dictionary definition 0-, 1- etc. are there to parse the date block delimited with dashes, and make sure the negative numbers are not effected
reps = {'"NAN"':'NAN', '"':'', '0-':'0,','1-':'1,','2-':'2,','3-':'3,','4-':'4,','5-':'5,','6-':'6,','7-':'7,','8-':'8,','9-':'9,', ' ':',', ':':',' }

txt = data_parser(my_text, reps)
outputfile.writelines(txt)

inputfile.close()
outputfile.close()
Author: marillion, 2012-08-13

3 answers

Eu usaria um laço for para iterar nas linhas do ficheiro de texto:

for line in my_text:
    outputfile.writelines(data_parser(line, reps))

Se quiser ler o ficheiro linha a linha em vez de carregar a coisa toda no início do programa, pode fazer algo do género:

inputfile = open('test.dat')
outputfile = open('test.csv', 'w')

# sample text string, just for demonstration to let you know how the data looks like
# my_text = '"2012-06-23 03:09:13.23",4323584,-1.911224,-0.4657288,-0.1166382,-0.24823,0.256485,"NAN",-0.3489428,-0.130449,-0.2440527,-0.2942413,0.04944348,0.4337797,-1.105218,-1.201882,-0.5962594,-0.586636'

# dictionary definition 0-, 1- etc. are there to parse the date block delimited with dashes, and make sure the negative numbers are not effected
reps = {'"NAN"':'NAN', '"':'', '0-':'0,','1-':'1,','2-':'2,','3-':'3,','4-':'4,','5-':'5,','6-':'6,','7-':'7,','8-':'8,','9-':'9,', ' ':',', ':':',' }

for i in range(4): inputfile.next() # skip first four lines
for line in inputfile:
    outputfile.writelines(data_parser(line, reps))

inputfile.close()
outputfile.close()
 10
Author: Joe Day, 2017-04-26 11:36:01
Pela resposta aceite, parece que o teu comportamento desejado é virar.
skip 0
skip 1
skip 2
skip 3
"2012-06-23 03:09:13.23",4323584,-1.911224,-0.4657288,-0.1166382,-0.24823,0.256485,"NAN",-0.3489428,-0.130449,-0.2440527,-0.2942413,0.04944348,0.4337797,-1.105218,-1.201882,-0.5962594,-0.586636

Em

2012,06,23,03,09,13.23,4323584,-1.911224,-0.4657288,-0.1166382,-0.24823,0.256485,NAN,-0.3489428,-0.130449,-0.2440527,-0.2942413,0.04944348,0.4337797,-1.105218,-1.201882,-0.5962594,-0.586636
Se isso está certo, então acho que algo como ...
import csv

with open("test.dat", "rb") as infile, open("test.csv", "wb") as outfile:
    reader = csv.reader(infile)
    writer = csv.writer(outfile, quoting=False)
    for i, line in enumerate(reader):
        if i < 4: continue
        date = line[0].split()
        day = date[0].split('-')
        time = date[1].split(':')
        newline = day + time + line[1:]
        writer.writerow(newline)

Seria um pouco mais simples do que as coisas reps.

 10
Author: DSM, 2012-08-13 15:24:40
Há algumas maneiras de fazer isto. Uma opção seria usar inputfile.read() em vez de inputfile.readlines() - teria de escrever um código separado para remover as primeiras quatro linhas, mas se quiser o resultado final como uma única cadeia de caracteres, isto poderá fazer mais sentido.

Uma segunda opção mais simples seria juntar as cordas depois de arrancar as primeiras quatro linhas com my_text = ''.join(my_text). Isto é um pouco ineficiente, mas se a velocidade não é uma grande preocupação, o código será mais simples.

Finalmente, se na verdade, quer a saída como uma lista de strings em vez de uma única string, você pode apenas modificar o seu analisador de dados para iterar sobre a lista. Isso pode ser parecido com isto.

def data_parser(lines, dic):
    for i, j in dic.iteritems():
        for (k, line) in enumerate(lines):
            lines[k] = line.replace(i, j)
    return lines
 2
Author: Julian, 2012-08-13 15:11:08