große dateien aufsplitten

Du hast eine Idee für ein Projekt?
Antworten
cwesche
User
Beiträge: 14
Registriert: Mittwoch 10. Februar 2010, 11:43

hallo liebe python-freunde,

ich hab aktuell mal wieder ein problem, welches ich zuvor mit awk gelöst habe, aber ich würde gern komplett auf python umsteigen.
mir lieben ascii dateien vor, im tabellenformat mit tabstop getrennt. in diese dateien wurden mehrere objekte (welche durch mehrere hundert zeilen definiert werden) hintereinander weggeschrieben. die erste spalte besitzt jeweils eine fortlaufende nummer...für jedes neue objekt wieder beginnend mit 1. hier ein beispiel:

Code: Alles auswählen

 
     1  1594  2968  -1956025.00  1712350.00  -62.938234  -55.115644  25.1506
     2  1594  2969  -1956025.00  1712325.00  -62.938358  -55.116037  25.1514
     3  1595  2969  -1956000.00  1712325.00  -62.938537  -55.115763  25.1499
     4  1596  2969  -1955975.00  1712325.00  -62.938716  -55.115490  25.1485
     5  1594  2970  -1956025.00  1712300.00  -62.938483  -55.116429  25.1522
     6  1595  2970  -1956000.00  1712300.00  -62.938662  -55.116156  25.1507
     7  1596  2970  -1955975.00  1712300.00  -62.938841  -55.115882  25.1493
     8  1597  2970  -1955950.00  1712300.00  -62.939020  -55.115608  25.1478
     9  1594  2971  -1956025.00  1712275.00  -62.938608  -55.116822  25.1529
    10  1595  2971  -1956000.00  1712275.00  -62.938787  -55.116548  25.1515
    11  1596  2971  -1955975.00  1712275.00  -62.938965  -55.116274  25.1500
    12  1597  2971  -1955950.00  1712275.00  -62.939144  -55.116001  25.1486
    13  1598  2971  -1955925.00  1712275.00  -62.939323  -55.115727  25.1471
    14  1599  2971  -1955900.00  1712275.00  -62.939502  -55.115454  25.1457
    15  1594  2972  -1956025.00  1712250.00  -62.938732  -55.117214  25.1537
     1  1595  2972  -1956000.00  1712250.00  -62.938911  -55.116941  25.1523
     2  1596  2972  -1955975.00  1712250.00  -62.939090  -55.116667  25.1508
     3  1597  2972  -1955950.00  1712250.00  -62.939269  -55.116393  25.1494
     4  1598  2972  -1955925.00  1712250.00  -62.939448  -55.116120  25.1479
     5  1599  2972  -1955900.00  1712250.00  -62.939626  -55.115846  25.1465
     6  1600  2972  -1955875.00  1712250.00  -62.939805  -55.115572  25.1450
     7  1594  2973  -1956025.00  1712225.00  -62.938857  -55.117607  25.1545
     8  1595  2973  -1956000.00  1712225.00  -62.939036  -55.117333  25.1530
     9  1596  2973  -1955975.00  1712225.00  -62.939215  -55.117059  25.1516
    10  1597  2973  -1955950.00  1712225.00  -62.939393  -55.116786  25.1501
    11  1598  2973  -1955925.00  1712225.00  -62.939572  -55.116512  25.1487
    12  1599  2973  -1955900.00  1712225.00  -62.939751  -55.116239  25.1472
    13  1600  2973  -1955875.00  1712225.00  -62.939930  -55.115965  25.1458
    14  1601  2973  -1955850.00  1712225.00  -62.940109  -55.115691  25.1443
    15  1594  2974  -1956025.00  1712200.00  -62.938982  -55.117999  25.1553
    16  1595  2974  -1956000.00  1712200.00  -62.939161  -55.117725  25.1538
    17  1596  2974  -1955975.00  1712200.00  -62.939339  -55.117452  25.1524
ich würde nun gern eine solche datei trennen, jeweils wenn ein neues objekt anfängt und diese in einzelne, durchnummerierte dateien schreiben...z.b.
datei1:

Code: Alles auswählen

     1  1594  2968  -1956025.00  1712350.00  -62.938234  -55.115644  25.1506
     2  1594  2969  -1956025.00  1712325.00  -62.938358  -55.116037  25.1514
     3  1595  2969  -1956000.00  1712325.00  -62.938537  -55.115763  25.1499
     4  1596  2969  -1955975.00  1712325.00  -62.938716  -55.115490  25.1485
     5  1594  2970  -1956025.00  1712300.00  -62.938483  -55.116429  25.1522
     6  1595  2970  -1956000.00  1712300.00  -62.938662  -55.116156  25.1507
     7  1596  2970  -1955975.00  1712300.00  -62.938841  -55.115882  25.1493
     8  1597  2970  -1955950.00  1712300.00  -62.939020  -55.115608  25.1478
     9  1594  2971  -1956025.00  1712275.00  -62.938608  -55.116822  25.1529
    10  1595  2971  -1956000.00  1712275.00  -62.938787  -55.116548  25.1515
    11  1596  2971  -1955975.00  1712275.00  -62.938965  -55.116274  25.1500
    12  1597  2971  -1955950.00  1712275.00  -62.939144  -55.116001  25.1486
    13  1598  2971  -1955925.00  1712275.00  -62.939323  -55.115727  25.1471
    14  1599  2971  -1955900.00  1712275.00  -62.939502  -55.115454  25.1457
    15  1594  2972  -1956025.00  1712250.00  -62.938732  -55.117214  25.1537
datei2:

Code: Alles auswählen

     1  1594  2968  -1956025.00  1712350.00  -62.938234  -55.115644  25.1506
     2  1594  2969  -1956025.00  1712325.00  -62.938358  -55.116037  25.1514
     3  1595  2969  -1956000.00  1712325.00  -62.938537  -55.115763  25.1499
     4  1596  2969  -1955975.00  1712325.00  -62.938716  -55.115490  25.1485
     5  1594  2970  -1956025.00  1712300.00  -62.938483  -55.116429  25.1522
     6  1595  2970  -1956000.00  1712300.00  -62.938662  -55.116156  25.1507
     7  1596  2970  -1955975.00  1712300.00  -62.938841  -55.115882  25.1493
     8  1597  2970  -1955950.00  1712300.00  -62.939020  -55.115608  25.1478
     9  1594  2971  -1956025.00  1712275.00  -62.938608  -55.116822  25.1529
    10  1595  2971  -1956000.00  1712275.00  -62.938787  -55.116548  25.1515
    11  1596  2971  -1955975.00  1712275.00  -62.938965  -55.116274  25.1500
    12  1597  2971  -1955950.00  1712275.00  -62.939144  -55.116001  25.1486
    13  1598  2971  -1955925.00  1712275.00  -62.939323  -55.115727  25.1471
    14  1599  2971  -1955900.00  1712275.00  -62.939502  -55.115454  25.1457
    15  1594  2972  -1956025.00  1712250.00  -62.938732  -55.117214  25.1537
etc.

ich habe noch nicht einmal eine ahnung, wie ich die sache angehen sollte. wenn ihr mir helfen könntet, wäre ich sehr sehr dankbar. auf für eine tipp für einen möglichen befehl.

grüße, christine
BlackJack

@cwesche: Meine Tipps wären das `csv`-Modul und `itertools.groupby()`. `itertools.count()` kann man in einer Lösung sicher auch gut gebrauchen.

Edit:

Code: Alles auswählen

from __future__ import with_statement
from itertools import count, groupby, imap
from operator import itemgetter

get_first = itemgetter(0)
get_second = itemgetter(1)


def group_objects(lines):
    """Returns an iterable of pairs of object number and iterable of lines.
    
    The object number starts at 0.
    """
    def mark_object_lines():
        counter = count()
        current_no = None
        for line in lines:
            first_value = int(line.split(None, 1)[0])
            if first_value == 1:
                current_no = counter.next()
            yield (current_no, line)
    return ((i, imap(get_second, g))
            for i, g in groupby(mark_object_lines(), get_first))


def main():
    with open('test.txt') as lines:
        for i, object_lines in group_objects(lines):
            with open('test%d.txt' % (i + 1), 'w') as out_file:
                out_file.writelines(object_lines)


if __name__ == '__main__':
    main()
cwesche
User
Beiträge: 14
Registriert: Mittwoch 10. Februar 2010, 11:43

danke für die prompte hilfe!!!
Antworten