2017-02-28 2 views
0

Ich habe eine GeoJSON-Datei, die eine Aufschlüsselung eines bestimmten geografischen Gebiets in ca. enthält. 7000 Zellen. Ich möchte a) öffnen Sie dieses geoJSON b) ändern Sie einige Daten (siehe Code unten) und c) schreiben Sie dieses modifizierte geoJSON auf die Festplatte. Nun, mein Problem ist, dass es, da es viele Zellen gibt, fast eine Minute dauert. Sehen Sie irgendeine Möglichkeit, die Geschwindigkeit dieser Funktion zu verbessern? Vielen Dank!Python - Erhöhen lesen/ändern/schreiben Geschwindigkeit?

def writeGeoJSON(param1, param2, inputdf): 
    with open('ingeo.geojson') as f: 
     data = json.load(f) 
    for feature in data['features']: 
     currentfeature = inputdf[(inputdf['SId']==feature['properties']['cellId']) & (inputdf['param1']==param1) & (inputdf['param2']==param2)] 
     if (len(currentfeature) > 0): 
      feature['properties'].update({"style": {"opacity": currentfeature.Opacity.item()}}) 
     else: 
      feature['properties'].update({"style": {"opacity": 0}}) 
    end = time.time() 
    with open('outgeo.geojson', 'w') as outfile: 
     json.dump(data, outfile) 
+1

Vielleicht berechnen 'inputdf [(inputdf [ 'param1'] == param1) & (inputdf ['param2'] == param2)] außerhalb der Schleife. –

+0

Zuerst, [profile] (http://stackoverflow.com/a/582337/3005167) Ihre Funktion, um herauszufinden, ob der Engpass in I/O oder Verarbeitung ist. Alles andere ist nur Angeln im Dunkeln – kazemakase

+0

@Alex Excellent! Ich habe denselben Punkt in meiner Antwort erwähnt. Ich habe es in der Minute bemerkt, als die Frage gestellt wurde ... Ich habe 9 Minuten gebraucht, um diese Frage von meinem Handy aus zu beantworten! xD – varun

Antwort

2

Es gibt eine seriellen Code-Optimierung möglich in Ihrem Code. Sie haben die Zeile:

currentfeature = inputdf[(inputdf['SId']==feature['properties']['cellId']) & (inputdf['param1']==param1) & (inputdf['param2']==param2 

Beachten Sie, dass die letzten beiden Kontrollen außerhalb des for Schleife gesetzt werden. Es ist eine redundante Prüfung, die für jede Iteration in der for Schleife viele CPU-Taktzyklen benötigt !!! Sie können das gleiche ändern wie:

paramMatch=inputdf['param1']==param1 & inputdf['param2']==param2 
for feature in data['features']: 
    currentfeature = inputdf[(inputdf['SId']==feature['properties']['cellId']) & paramMatch] 

, dass Ihr Programm laufen lassen müssen viel schneller!

Das heißt, wenn Sie bessere Ausführungszeiten benötigen (höchstwahrscheinlich nicht notwendig), versuchen Sie, das multiprocessing Modul zu verwenden, um den Verarbeitungsteil des Codes zu parallelisieren. Sie können versuchen, die Arbeitslast in der Schleife for zu teilen.

Probieren Sie apply_async oder map_async zu einem Block von Iterationen, um die Dinge zu beschleunigen!

+0

Danke, dass die Laufzeit um 60% verkürzt! Ich werde versuchen, es auch parallel laufen zu lassen. :) –

+0

Super! Stellen Sie sicher, dass Sie das 'Threading'-Modul vermeiden und das 'Multiprocessing'-Modul verwenden, wenn Sie sich in Cpython (der Standard-Python-Distribution) befinden. Ansonsten kann das auch eine Option sein! – varun

+1

Ja, ich habe mit 'Multiprocessing' gearbeitet, vorher in ein paar Uni-Zuweisungen, also bin ich vertraut :) So weit ich weiß,' threading' macht keine echte Parallelverarbeitung bc der GIL. :) –

1

[Neben @varun-Optimierung, einschließlich einem @ romain-aga Vorschlag.]

Fügen Sie diese am Anfang der Funktion:

zero_style = {"opacity": 0} 

Und die bedingten verändern werden:

if (len(currentfeature) > 0): 
    feature['properties']['style'] = {"opacity": currentfeature.Opacity.item()} 
else: 
    feature['properties']['style'] = zero_style 

ich habe den Eindruck, dass mehr über inputdf Art zu wissen, zu einem besseren Optimierung führen würde (vielleicht if currentfeature: lenken ist genug? vielleicht ist ? Besser)


CPython Unter der Annahme, erwarte ich, dass dies besser zu sein (besser um Vergebung zu bitten, als um Erlaubnis):

try: 
    value = {"opacity": currentfeature.Opacity.item()} 
except NotSureWhatExceptionMaybeAttributeError: 
    value = zero_style 
feature['properties']['style'] = value 
+0

+1 für diese detaillierte Beobachtung. Das ist ein interessanter Einblick in den Overhead des Python-Wörterbuch-Erstellens in jeder Iteration. Ich werde experimentieren und prüfen, ob es einen Unterschied macht. Ich denke, es wird es ein bisschen schneller machen! :) – varun

Verwandte Themen