2017-05-10 2 views
2

Ich habe eine Liste von Dateien 1.dat, ..., N.dat in einem Verzeichnis, das ich lesen und analysieren möchte.Iteratives Lesen von sortierten Dateien in Python

Ich habe die folgende

for f in os.listdir('.'): # read all the files in the directory 
    if f.endswith('.dat'): # use only the ones with .dat as extansion 
     print(f) 
     data1 = np.loadtxt(f) 
     # some operations on each file 

Auf diese Weise werden die Dateien in zufälliger Reihenfolge genommen, die Ausgabe Druck:

6.dat 
4.dat 
8.dat 
5.dat 
13.dat 
10.dat 
1.dat 
16.dat 
20.dat 
19.dat 

Also meine Frage, wie ich das Skript erzwingen die Dateien sortiert lesen? Von der Datei 1.dat bis N.dat.

+0

die Dateien in einer Liste anhängen könnte, dann die Liste sortieren? – CodeCupboard

Antwort

6

Sie müssen die vollständige Liste der Dateien abrufen und sie dann in der von Ihnen gewünschten Reihenfolge sortieren.

files = [f for f in os.listdir('.') if f.endswith('.dat')] 

Dies bringt Sie auf die Liste der .dat Dateien. Sie brauchen keine vollständige for Schleife und ein Listenverständnis ist schneller.

Der Trick beim Sortieren ist, dass Sie einen Schlüssel benötigen, der Ihnen die richtige Reihenfolge gibt. In diesem Fall wird für den Schlüssel auf den numerischen Wert umwandeln:

files.sort(key=lambda f: int(f[:-4])) 

Diese nur funktionieren wird, wenn Sie sicher sind, dass alle dat Dateien numerische Namen mit Ausnahme der letzten vier Zeichen lang sein.

Jetzt können Sie Ihre Liste verarbeiten:

for f in files: 
    data1 = np.loadtxt(f) 
    ... 

Für eine komplexere Sortieralgorithmus, würde ich die Bibliothek natsort empfehlen. Dann würde Ihr Sortierschritt aussieht

from natsort import natsorted 
files = natsorted(files) 

ODER

from natsort import humansorted 
files = humansorted(files) 

Die zweite Version ist locale-aware.

+0

@ChristianDean. Danke für die Lösung :) –

+0

Kein Problem man ;-) –

3
files = [] 
for f in os.listdir('.'): # read all the files in the directory 
    if f.endswith('.dat'): # use only the ones with .dat as extansion 
     files.append(f) 
files.sort(key=lambda x:int(x.split('.')[0])) 
for f in files: 
    data1 = np.loadtxt(f) 
    # some operations on each file 
+3

Nein, weil '6' auf diese Weise nicht vor' 50' sortiert wird. –

+0

@Meccano Dank für Ihre Antwort, aber als @MadPhysicist dieses Skript beobachten wird in einer falschen Weise sortieren, wie '1.dat 10.DAT 11.dat 12.dat 13.dat 14.dat 15.dat' –

+1

Ich habe meinen Beitrag bearbeitet, ich habe eine benutzerdefinierte Schlüsselfunktion gemacht, um den numerischen Wert der Zahl und nicht das lexikographische zu nehmen. – Meccano

2

Sie können Ihre Dateiliste mit dem key Parameter der .sort() Funktion sortieren. Aber um die Dateien zu sortieren, basierend auf ihren numerischen Wert, müssen Sie den numerischen Teil des Dateinamens in eine ganze Zahl konvertieren:

files = [file for file in os.listdir('.') if file.endswith('.dat')] 
files.sort(key=lambda filename: int(filename[:-4])) 

for f in files: 
    data1 = np.loadtxt(f) 
+0

'Dateiname [0]' ist nur das erste Zeichen –

3

Du hast die richtige Idee. Sie müssen nur die Dateien auf "menschlich-natürliche" Weise sortieren. Es gibt ein paar verschiedene Ansätze; packen Sie sie mit Nullen und sortieren Sie dann zum Beispiel. Ich mag diese ein:

import re 
def sorted_nicely(iter): 
    """ Sort the given iterable in the way that humans expect; i.e, 
    '2fast2furious' < '11fast11furious' 
    """ 
    convert = lambda text: int(text) if text.isdigit() else text 
    alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ] 
    return sorted(iter, key=alphanum_key) 

Beispiel:

>>> print(sorted_nicely('a.dat 6.dat 4.dat 8.dat 5.dat 13.dat 10.dat 16.dat 18.dat 20.dat'.split()) 
['4.dat', '5.dat', '6.dat', '8.dat', '10.dat', '13.dat', '16.dat', '18.dat', '20.dat', 'a.dat'] 
+0

Was passiert, wenn Sie sowohl Integer als auch Textnamen haben? Ziemlich sicher, dass Sie einen Fehler bekommen, wenn Sie '['a.dat', '1.dat']' haben. –

+1

Nein. Dem Beispiel zur Veranschaulichung hinzugefügt. –

+1

Mein Fehler. BTW, das ist eine vereinfachte Version der 'natsort' Bibliothek. –