Hallo,
ich habe eine riesige Text Datei in der Dreiecke und ihre Punkte aufgelistet sind.
Z.B.:
1 3 5 6 (1. Dreieck mit Punkt 3, 5 und 6)
2 4 6 7
3 6 7 8
...
weiter unten kommt die Liste mit den Punkten und ihren Koordinaten:
3 33.55 22.44 5.4
5 22.44 66.77 7.3
6 11.77 66.88 1.5
...
Jetzt soll das umsortiert werden in eine Datei wo die Dreiecksnummer steht und dann gleich die Koordinaten also:
1
33.55 22.44 5.4
22.44 66.77 7.3
11.77 66.88 1.5
...
Hoffe ich hab mich nicht zu konfus ausgedrückt.
Ich kann ja einfach die erste Datei mit xreadlines durchlesen und alles in Listen packen, dann umsortieren und wieder in eine andere Datei schreieben.
Problematisch wird das aber wahrscheinlich weil die erste Datei rund 26 MB groß ist.
Was meint Ihr geht das mit Listen, oder gibt es da was effektiveres?
Z.B. sowas wie: Wenn Dreieckszeile, dann suche nach den Punkten weiter unten uns schreibe sie raus.
Ich muss allerdings noch sagen, dass meine Pythonkenntnisse nicht sehr weit gehen. Deswegen wärs nett wenn jemand was mit Beispielen posten könnte.
Danke schonmal!
Riesige Text Dateien
Woran erkennst Du denn wo die Dreiecke aufhören und die Koordinaten beginnen?
26 MiB ist heutzutage nun auch nicht mehr sooo viel. Ich würde erst einmal schauen, ob ganz naives, komplettes Einlesen funktioniert und erst bei Problemen komplizierteren Code schreiben.
Da wäre der erste Schritt dann Dreiecke überlesen, Koordinaten komplett lesen, Datei neu öffnen und die Dreiecke zeilenweise verarbeiten.
Falls Du am Ausgabeformat noch etwas drehen kannst, würde ich vorschlagen ein komplettes Dreieck pro Zeile zu speichern. Sonst macht man sich die Weiterverarbeitung unnötig schwerer.
Warum soll eigentlich umsortiert werden? Zumindest wenn es sich um grösstenteils zusammenhängende "meshes" handelt, dürften die Dateien erheblich grösser werden, weil alle geteilten Punkte jetzt pro beteiligtem Dreieck einen eigenen "Datensatz" bekommen.
26 MiB ist heutzutage nun auch nicht mehr sooo viel. Ich würde erst einmal schauen, ob ganz naives, komplettes Einlesen funktioniert und erst bei Problemen komplizierteren Code schreiben.
Da wäre der erste Schritt dann Dreiecke überlesen, Koordinaten komplett lesen, Datei neu öffnen und die Dreiecke zeilenweise verarbeiten.
Falls Du am Ausgabeformat noch etwas drehen kannst, würde ich vorschlagen ein komplettes Dreieck pro Zeile zu speichern. Sonst macht man sich die Weiterverarbeitung unnötig schwerer.
Warum soll eigentlich umsortiert werden? Zumindest wenn es sich um grösstenteils zusammenhängende "meshes" handelt, dürften die Dateien erheblich grösser werden, weil alle geteilten Punkte jetzt pro beteiligtem Dreieck einen eigenen "Datensatz" bekommen.
-
- User
- Beiträge: 23
- Registriert: Freitag 31. Oktober 2008, 15:41
Die Daten sollen umgeschrieben werden weil die Daten von einem Programm an ein anderes übergeben werden sollen, das nur dieses Format so wie von mir beschrieben lesen kann.
Ich habe schon mal was ähnliches mit größeren Dateien gemacht und habe mich damals auch schon gefragt ob das nicht besser ginge als alles in Listen zu lesen. Könnte mir vorstellen, das das den Speicher ganz schön aufbläht. Aber ist nur eine Vermutung.
Hat noch jemand Ideen, wie man anhand meines Beispiels in Textdateien "Datenabankähnlich" suchen könnte?
Ich habe schon mal was ähnliches mit größeren Dateien gemacht und habe mich damals auch schon gefragt ob das nicht besser ginge als alles in Listen zu lesen. Könnte mir vorstellen, das das den Speicher ganz schön aufbläht. Aber ist nur eine Vermutung.
Hat noch jemand Ideen, wie man anhand meines Beispiels in Textdateien "Datenabankähnlich" suchen könnte?
In dem man die Punkte in eine Datenbank schreibt. Ggf. sqlite.spinneratz hat geschrieben: Hat noch jemand Ideen, wie man anhand meines Beispiels in Textdateien "Datenabankähnlich" suchen könnte?
@spinneratz: Wenn Du wirklich alles aus der Datei in Listen stecken würdest, solltest Du noch einmal das Tutorial aus der Python-Dokumentation durcharbeiten. Es gibt noch mehr Datentypen in den "built ins" als Listen.
-
- User
- Beiträge: 23
- Registriert: Freitag 31. Oktober 2008, 15:41
Ich möchte allerdings nicht extra eine Datenbank aufsetzen...
@spinneratz: Ich würde eine Datenbank hier auch als "Overkill" sehen, aber Datenbank heisst ja nicht rieseiger, externer DBMS-Server-Prozess. `anydbm`, `shelve`, `sqlite` sind alles Datenbanken und da braucht man nichts aufsetzen.
-
- User
- Beiträge: 23
- Registriert: Freitag 31. Oktober 2008, 15:41
Habe mir schon die anderen Datentypen angesehen. Aber ich das Problem dass man während dem lesen einer Zeile gleich weiter unten in der Datei nach den Punktzahlen sucht wird damit glaube ich nicht gelöst.
Wenn man alles einliest und in Listen speichert, welche Datenstruktur würde denn hier Vorteile bringen? Dictionaries? Weiß nicht...?
Außerdem fehlt es mir ehrlich an Erfahrung welche Listentypen hier geeignet sind.
Wenn man alles einliest und in Listen speichert, welche Datenstruktur würde denn hier Vorteile bringen? Dictionaries? Weiß nicht...?
Außerdem fehlt es mir ehrlich an Erfahrung welche Listentypen hier geeignet sind.
Hier ein Vorschlag.
Annahme: Dreiecksecken lassen sich mit int() umwandeln.
Ausgabe:
Annahme: Dreiecksecken lassen sich mit int() umwandeln.
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from StringIO import StringIO
from pprint import pprint
data = """1 3 5 6
2 4 6 7
3 6 7 8
3 33.55 22.44 5.4
5 22.44 66.77 7.3
6 11.77 66.88 1.5
4 1.0 2.0 3.0
7 10.0 11.0 12.0
8 20.0 30.0 40.0"""
class Punkt(object):
def __init__(self, id, x=None, y=None, z=None):
self.id, self.x, self.y, self.z = id, x, y, z
def __repr__(self):
return "<Punkt %i: %f, %f, %f>" % (self.id, self.x, self.y, self.z)
class Dreieck(object):
def __init__(self, id, x, y, z):
self.id, self.x, self.y, self.z = id, x, y, z
def __repr__(self):
return "<Dreieck %i: %r, %r, %r>" % (self.id, self.x, self.y, self.z)
punkte = {}
dreiecke = {}
for line in StringIO(data):
id, x, y, z = line.split()
id = int(id)
try:
# Dreieck
ix, iy, iz = int(x), int(y), int(z)
dreiecke[id] = Dreieck(id,
punkte.setdefault(ix, Punkt(ix)),
punkte.setdefault(iy, Punkt(iy)),
punkte.setdefault(iz, Punkt(iz)))
except:
# Punkt
fx, fy, fz = float(x), float(y), float(z)
punkte[id] = Punkt(id, fx, fy, fz)
for dreieck in dreiecke.values():
dreieck.x = punkte[dreieck.x.id]
dreieck.y = punkte[dreieck.y.id]
dreieck.z = punkte[dreieck.z.id]
pprint(dreiecke)
Code: Alles auswählen
% python dreieck.py
{1: <Dreieck 1: <Punkt 3: 33.550000, 22.440000, 5.400000>, <Punkt 5: 22.440000, 66.770000, 7.300000>, <Punkt 6: 11.770000, 66.880000, 1.500000>>,
2: <Dreieck 2: <Punkt 4: 1.000000, 2.000000, 3.000000>, <Punkt 6: 11.770000, 66.880000, 1.500000>, <Punkt 7: 10.000000, 11.000000, 12.000000>>,
3: <Dreieck 3: <Punkt 6: 11.770000, 66.880000, 1.500000>, <Punkt 7: 10.000000, 11.000000, 12.000000>, <Punkt 8: 20.000000, 30.000000, 40.000000>>}
Moin,
nicht schön, aber selten:
Zuerst werden die Positionen aller Punkte in einem Index gespeichert. Danach wird die Datei wieder von vorn durchlaufen und alle Dreiecke im neuen Format gespeichert. Da im ersten Durchlauf die Punkte indiziert wurden, kann man diese Punkte direkt anspringen, lesen und verarbeiten.
Ich nehme hier einfach mal an, dass die Dreiecksdefinitionen von den Punktdefinitionen mit einer Leerzeile getrennt sind.
Gruß,
Manuel
nicht schön, aber selten:
Code: Alles auswählen
index = dict()
with open("test.txt") as data:
# first index all coordinates
# skip triangle defs
while data.readline().strip():
pass
# collect index coordinates
line = data.readline()
while line:
point = line.split()[0]
index[point] = data.tell() - len(line)
line = data.readline()
# back to begin of file
data.seek(0)
# write new file
with open("new.txt", "w") as new_data:
# go through all triangles and get coords using index
while True:
triangle_def = data.readline().strip().split()
current_pos = data.tell()
if not triangle_def:
break
# collect data
triangle_data = list()
triangle_data.append(triangle_def[0] + "\n")
for point in triangle_def[1:4]:
# jump to point definition
pos = index[point]
data.seek(pos)
coords = data.readline().rstrip().split()
coords = ' '.join(coords[1:])
# write coords
triangle_data.append(coords + "\n")
new_data.writelines(triangle_data)
# back to next triangle def
data.seek(current_pos)
Ich nehme hier einfach mal an, dass die Dreiecksdefinitionen von den Punktdefinitionen mit einer Leerzeile getrennt sind.
Gruß,
Manuel
-
- User
- Beiträge: 23
- Registriert: Freitag 31. Oktober 2008, 15:41
Hey cool. Muss mir die Codes mal in Ruhe durchdenken...
Nachtrag: Vor den Dreiecken steht ein DR
und bei den Punkten ein P somit hat man Key Wörter um zu ckecken ob ein Dreicke oder Punkt losgeht
Nachtrag: Vor den Dreiecken steht ein DR
und bei den Punkten ein P somit hat man Key Wörter um zu ckecken ob ein Dreicke oder Punkt losgeht