Hallo,
ich bin neu hier und auch in Python bin ich noch recht unerfahren.
Ich versuche mein Problem mal anhand eines Minimalbeispiels zu erklären:
Datei 1 hat eine Tabelle mit x Zeilen und y Spalten:
243 100110100
422 011100101
643 101000110
823 100010010
425 011000100
1075 100110100
1154 111011010
Datei 2 sieht folgendermaßen aus:
243 643 3
422 643 2
643 643 1
823 823 1
425 1075 2
1075 1075 1
1154 1154 1
Die erste Zahlen in den ersten Spalten stimmen überein. Ich möchte nun für jede Zeile eine Datei schreiben, in der genauso viele Zeilen aus Datei 1 stehen wie in Spalte 3 von Datei 2 angegeben. Für jede Zeile würde ich spontan eine for Schleife schreiben, aber da stört die unregelmäßige Anzahl an Zeilen die ich jeweils raus ziehen möchte. Vielleicht ist auch was mit einer if Abfrage möglich (wenn Zahl in Spalte 1 in beiden Dateien übereinstimmen, dann ziehe soviel Zeilen raus wie in Spalte 3 genannt :K )?
Für mein Minimalbeispiel sähen die gewünschten Ausgabedateien folgendermaßen aus:
hier sieben Zeilen in Datei 1- also sieben Dateien:
erste:
243 100110100
422 011100101
643 101000110
zweite:
422 011100101
643 101000110
dritte:
643 101000110
vierte:
823 100010010
fünfte:
425 011000100
1075 100110100
sechste:
1075 100110100
siebte:
1154 111011010
Wäre toll wenn jemand eine Idee hätte wie ich das Problem lösen kann. Vielen Dank schonmal im Voraus
P.S.: Die Dateien sind natürlich wesentlich größer. Ich habe meinen Code hier nicht reingestellt, weil das nur ein Teilproblem darstellt. Es wird noch transponiert, zusammengefasst, gerechnet,.....
unterschiedliche Anzahl von Zeilen aus Datei ziehen
Hallo und willkkommen im Forum!
Zeig doch mal, was du bereit an Code dafür geschrieben hast. Damit lässt sich sicher arbeiten. Außerdem müsstest du noch genauer spezifizieren, was du mit "große Dateien" meinst.
Sebastian
Zeig doch mal, was du bereit an Code dafür geschrieben hast. Damit lässt sich sicher arbeiten. Außerdem müsstest du noch genauer spezifizieren, was du mit "große Dateien" meinst.
Sebastian
Das Leben ist wie ein Tennisball.
große Dateien heißt, dass die reinen .txt Dateien über 80 und 5MB groß sind.
Hier mal der entscheidende Teil aus dem Code den ich schon geschrieben habe
Einlesen der Dateien mit readlines()
Hier mal der entscheidende Teil aus dem Code den ich schon geschrieben habe
Einlesen der Dateien mit readlines()
Code: Alles auswählen
f_out=open('ausgabe.txt','w')
li1=[]
gts_split=lines1[0].rstrip().split(',')[2:]
for g in xrange(len(gts_split)):
li1.append(gts_split[g]) #Namen aus erster Spalte
li1[g]+=' ' #Leerzeichen sind noetig fuer Weiterverwendung in anderem Programm
for i in xrange(1,len(lines1)):
split1=re.split(',',lines1[i].rstrip())[2:]
for j in xrange(len(split1)):
li1[j]+=split1[j]
result=transposed2(li1) #Werte werden transponiert
for zeile in li1:
f_out.write('%s\n'%zeile)
f_out.close()
Ok, das sieht ja ein wenig nach Chaos aus bei dir... Ich mache mal einen Vorschlag:
Code: Alles auswählen
>>> spam = """243 100110100
... 422 011100101
... 643 101000110
... 823 100010010
... 425 011000100
... 1075 100110100
... 1154 111011010"""
>>> eggs = """243 643 3
... 422 643 2
... 643 643 1
... 823 823 1
... 425 1075 2
... 1075 1075 1
... 1154 1154 1"""
>>> def parse_spam(row):
... x, y = row.split()
... return int(x), y
...
>>> def parse_eggs(row):
... return map(int, row.split())
...
>>> foo = map(parse_spam, spam.splitlines())
>>> bar = map(parse_eggs, eggs.splitlines())
>>> baz = dict((row[0], index) for (index, row) in enumerate(foo))
>>> for elem, _, count in bar:
... start = baz[elem]
... print foo[start:start+count]
...
[(243, '100110100'), (422, '011100101'), (643, '101000110')]
[(422, '011100101'), (643, '101000110')]
[(643, '101000110')]
[(823, '100010010')]
[(425, '011000100'), (1075, '100110100')]
[(1075, '100110100')]
[(1154, '111011010')]
Das Leben ist wie ein Tennisball.
ja so sehen leider alle meine Skripte aus: Chaos pur Aber ich lerne ja noch...
Das Beispiel funktioniert, aber wenn ich das auf die echten Daten anwende, bekomme ich folgende Fehlermeldung:
foo = map(parse_spam, spam.splitlines())
AttributeError: 'list' object has no attribute 'splitlines'
Ich hab den Fehler gegoogelt aber keine passende Antwort gefunden, zumindest keine die ich verstehe.
In den echten Datensätzen haben die Spalten noch Überschriften. Kann das evtl. zu Problemen führen?
Das Beispiel funktioniert, aber wenn ich das auf die echten Daten anwende, bekomme ich folgende Fehlermeldung:
foo = map(parse_spam, spam.splitlines())
AttributeError: 'list' object has no attribute 'splitlines'
Ich hab den Fehler gegoogelt aber keine passende Antwort gefunden, zumindest keine die ich verstehe.
In den echten Datensätzen haben die Spalten noch Überschriften. Kann das evtl. zu Problemen führen?
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Dann scheint dein `spam` eben schon eine Liste zu sein und nicht wie bei EyDu ein String, d.h. du kannst `.splitlines()` streichen.
Michael Markert ❖ PEP 8 Übersetzung ❖ Tutorial Übersetzung (3.x) ⇒ Online-Version (Python 3.3) ❖ Deutscher Python-Insider ❖ Projekte
und der nächste Fehler:
Traceback (most recent call last):
File "tscan_pipe2.py", line 30, in <module>
foo = map(parse_spam, spam)
File "tscan_pipe2.py", line 25, in parse_spam
x,y=row.split()
ValueError: need more than 1 value to unpack
ich hab `.splitlines()`gestrichen
hier noch mal kurz der Code:
Traceback (most recent call last):
File "tscan_pipe2.py", line 30, in <module>
foo = map(parse_spam, spam)
File "tscan_pipe2.py", line 25, in parse_spam
x,y=row.split()
ValueError: need more than 1 value to unpack
ich hab `.splitlines()`gestrichen
hier noch mal kurz der Code:
Code: Alles auswählen
import re
f=open('Datei1.txt')
spam=f.readlines()[:100]
f.close()
f=open('Datei2.txt')
eggs=f.readlines()
f.close()
f_out=open('Ausgabe.txt','w')
li1=[]
def parse_spam(row):
x,y=row.split()
return int(x),y
def parse_eggs(row):
return map(int, row.split())
foo = map(parse_spam, spam)
bar = map(parse_eggs, eggs)
bez=dict((row[0],index) for(index,row) in enumerate(foo))
for elem, _, count in bar:
start=baz[elem]
print foo[start:start+count]
f_out.close()
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Schluss mit dem Cargo-Cult-Programmieren!
Du solltest Snippets nur verwenden, wenn du sie verstehst.
Deine Daten unterscheiden sich erheblich von EyDu's Daten, deine liegen als Listen vor, seine als String.
`split` trennt den String an dem uebergebenen Trennzeichen in Listen auf - per default bei jedem whitespace-Zeichen.
Du hast zwei Moeglichkeiten: Du aenderst das Einlesen der Daten und veraenderst sie dort gleich zur gewuenschten Form, oder du fuegst sie erst wieder zu einem String zusammen.
Fuer 1:
Du solltest Snippets nur verwenden, wenn du sie verstehst.
Deine Daten unterscheiden sich erheblich von EyDu's Daten, deine liegen als Listen vor, seine als String.
`split` trennt den String an dem uebergebenen Trennzeichen in Listen auf - per default bei jedem whitespace-Zeichen.
Du hast zwei Moeglichkeiten: Du aenderst das Einlesen der Daten und veraenderst sie dort gleich zur gewuenschten Form, oder du fuegst sie erst wieder zu einem String zusammen.
Fuer 1:
Code: Alles auswählen
with open("Datei.txt") as f:
foo = list()
for _ in xrange(100):
line = f.readline().split()
x, y = line.split(maxsplit=1)
foo.append(int(x), y)
with open("Datei2.txt") as f:
bar = list()
for line in f:
values = [int(x) for x in line.split()]
bar.extend(values)
Michael Markert ❖ PEP 8 Übersetzung ❖ Tutorial Übersetzung (3.x) ⇒ Online-Version (Python 3.3) ❖ Deutscher Python-Insider ❖ Projekte