2017-06-05 3 views
-3

Ich habe eine Datei, die wie folgt (dh zufällige Kombination von 2/3 aufeinanderfolgenden Zeilen) aussieht:Python Modifizieren CSV Daten

String A 
String B 
String C 
<Blank Row> 
String D 
String E 
<Blank Row> 
String F 
String G 
String H 
<Blank Row> 
String I 
String J 
String K 
<Blank Row> 
String L 
String M 

I die Ausgabedatei die mittlere Reihe entfernen soll, wenn gibt es 3 aufeinanderfolgende Reihen und transponiere die 2 verbleibenden Zeilen. Falls es nur 2 Zeilen gibt, sollten sie transponiert werden. Das Endergebnis sollte so aussehen.

String A,String C 
String D,String E 
String F,String H 
String I,String K 
String L,String M 

Irgendwelche Hinweise, wie Sie dies tun können?

+3

Jeder Code, den Sie bisher geschrieben haben? (Bitte poste es; da SO kein Kodierungsdienst ist, ist deine Frage, wie geschrieben, off-topic.) – DyZ

+0

Eine Zeile: ''\ n'.join ([' {}, {} '. Format (l [ 0], l [-1]) für l in [b.splitlines() für b in f_in.read(). Split ('\ n \ n')]]) ' – dawg

Antwort

1

Sie können groupby und count von itertools Modul zusammen mit list comprehension verwenden.

Diese Antwort ist ein wenig hacky, aber mach den Trick. Sehen Sie sich die Kommentare an, um die dahinter stehende Logik besser zu verstehen.

Ich gehe davon aus, dass Ihr Eingang ist der Eingang, den Sie in einer Datei mit dem Namen gaben wird my_input_file und Ausgabedatei output_file genannt:

from itertools import groupby, count 

# Read the file and split by the space between Value and its number 
# Leave the case where the empty string '' exists without splitting its spaces 
with open("my_input_file", 'r') as f: 
    data = (k.split() if k != '' else k for k in f.read().splitlines()) 

# Group the fields splitted, which are lists, in data 
# And separate them by the field where the string 'Blank' exists 
sub = [list(v) for _, v in groupby(data, lambda x: isinstance(x, list))] 

final = [] 
for elm in sub: 
    # if the lenght of the grouped elements is > 1 
    if len(elm) >1: 
     # Convert the number of the values into an int 
     # For further calculations 
     dd = map(lambda x: [x[0], int(x[1])], elm) 

     # Group the consecutive numbers of elem 
     for _,v in groupby(dd , lambda x,y=count(): x[1] - next(y)): 
      # If there is a consecutive numbers 
      bb = list(v) 
      if len(bb) >1: 
       # Conveert them into strings. Then, append the first and the final one to the final list 
       final.append(' '.join(map(str, bb[0])) + ',' + ' '.join(map(str, bb[-1]))) 

      # If there is'nt any consecutif numbers. Append the element to the final list 
      else: 
       final.append(" ".join(map(str, bb[0]))) 


# create the output file 
with open("output_file", 'a') as f: 
    for k in final: 
     f.write(k + '\n') 

Dieser Code wird ausgegeben eine Datei, die enthält:

Value 1,Value 3 
Value 4,Value 5 
Value 6,Value 8 
Value 9,Value 11 
Value 12,Value 13 

Testen Sie diesen Code und lassen Sie Ihre Rückmeldungen, wenn Sie irgendwelche haben, oder vielleicht, melden Sie bitte Fehler, wenn Sie einen von ihnen gefunden haben.

Edit:

nach Ihren zuletzt.

Wenn Ihre Eingabedatei:

What Test 
Makes No Sense 
is This 

My name 
Is Sample 123 

Your Name 
is ABC 2134 

What is you 
technical question don't know 
name? 

Der Trick ist so einfach. Sie können etwas tun, nur mit groupby von itertools Modul:

from itertools import groupby 

with open("my_input_file", 'r') as f: 
    data = f.read().splitlines() 

final = [list(v) for _, v in groupby(data, lambda x: x != '')] 

with open("ouput_file", 'a') as f: 
    for k in final: 
     if k != ['']: 
      f.write(k[0] + ',' + k[-1] + '\n') 

Und wird Ihre Ausgabedatei:

What Test ,is This 
My name ,Is Sample 123 
Your Name ,is ABC 2134 
What is you ,name? 
+0

Vielen Dank für Ihre Hilfe, die uns nicht eine Zeichenfolge, aber eigentlich ein Leerzeichen. Ich habe die Frage aktualisiert, um die Ausgabe besser darzustellen.Ich erhalte den folgenden Fehler "ValueError: ungültiges Literal für int() mit Basis 10: 'STRINGVALUE'" – misguided

+0

dd = Karte (Lambda x: [x [0], int (x [1])], Ulme) scheint sei das Problem, vielleicht liegt es daran, dass ich die Frage formuliert habe. – misguided

+0

Sie bearbeiten viel Ihre Frage! :/bleib ruhig und füge hinzu, wie deine Datei ist. Der zweite Wert ist eine Zeichenkette, ein int oder was? –

0

Um zu drehen: kennen Sie alle Linien am Ende eine neue Linie haben

with open("PATH TO FILE.txt", r) as file: 
    input = file.read() 
    input.replace("\n", "") 

für die Linien, die nur Leerräume haben oder sie zu identifizieren. Bis jetzt:

with open("PATH TO FILE.txt", r) as file: 
     input = file.read() 
     if not line.strip(): 
      input.replace("\n", "") 

und Sie können eine Zählung halten oder eine while-Schleife tun, so dass Sie zählen, bis Sie die Zeile mit nur weißen Räumen treffen und während jeder Zeile in einer Liste oder etwas setzen Zählen, wenn Sie 3 gezählt Nimm den ersten und den dritten, sonst schnapp dir beide. Denken Sie daran, die Zählung zurückzusetzen