Ontcijferen van tekstbestanden met Python

Ik probeer een reeks tekstbestanden te ontleden en ze op te slaan als CSV-bestanden met Python (2.7.3). Alle tekstbestanden hebben een header van 4 regels die moet worden verwijderd. De datalijnen hebben verschillende scheidingstekens, waaronder ” (citaat), – (streepje), : kolom en lege ruimte. Ik vond het lastig om het in C++ te coderen met al deze verschillende scheidingstekens, dus besloot ik het in Python te proberen om het te horen is relatief gemakkelijker te doen in vergelijking met C/C++.

Ik heb een stukje code geschreven om het te testen op een enkele regel gegevens en het werkt, maar het lukte me niet om het voor het eigenlijke bestand te laten werken. Voor het ontleden van een enkele regel gebruikte ik het tekstobject en de “replace” -methode. Het lijkt erop dat mijn huidige implementatie het tekstbestand als een lijst leest, en er is geen vervangingsmethode voor het lijstobject.

Als beginner in Python liep ik op dit punt vast. Alle input wordt op prijs gesteld!

Bedankt!

# 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()

Antwoord 1, autoriteit 100%

Ik zou een for-lus gebruiken om de regels in het tekstbestand te herhalen:

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

Als je het bestand regel voor regel wilt lezen in plaats van het hele ding aan het begin van het script te laden, kun je zoiets als dit doen:

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()

Antwoord 2, autoriteit 65%

Uit het geaccepteerde antwoord lijkt het erop dat uw gewenste gedrag is om te keren

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

in

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

Als dat juist is, dan denk ik zoiets

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)

zou een beetje eenvoudiger dan de repsstuff.

zijn


Antwoord 3, Autoriteit 12%

Er zijn een paar manieren om te gaan over dit. Een optie zou zijn om gebruik te maken inputfile.read()in plaats van inputfile.readlines()– je nodig hebt om aparte code op de eerste vier regels strip te schrijven, maar als u de uiteindelijke uitvoer als één tekenreeks willen hoe dan ook, zou dit het meest logisch.

Een tweede, eenvoudigere mogelijkheid zou zijn om de snaren vervoegen na het strepen van de eerste vier regels met my_text = ''.join(my_text). Dit is een beetje inefficiënt, maar als snelheid is niet een grote zorg, wordt de code eenvoudigste zijn.

Tot slot, als u daadwerkelijk wilt de output als een lijst van strings in plaats van één tekenreeks, kunt u gewoon uw data parser wijzigen om itereren over de lijst. Dat zou ziet er ongeveer als volgt uit:

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

Other episodes