2016-04-16 3 views
0

Ich mache eine Molekulardynamik-Simulation in Python mit einer großen Anzahl von Partikeln. Hier muss ich x-Position, y-Position, z-Position, x-Geschwindigkeit, y-Geschwindigkeit, z-Geschwindigkeit, x-Beschleunigung, y-Beschleunigung, z-Beschleunigung, x-Kraft, y-Kraft verfolgen , Z-Kraft, Potenzial für alle 500 oder 1000 Teilchen zusammen mit der kinetischen Energie, potentielle Energie, Gesamtenergie des Systems in jedem Zeitintervall. Um diese Daten zu speichern ich derzeit in eine Datei in der folgenden Art und Weise schreibe:Speichern von Simulationsdaten in Python

from numpy import* 
... 
f=open('myMD.dat','w') 
while t<=tmax: 
    s='%3.3f\t\t'%(t) # writing the time to the file 
    f.write(s) 
    for i in range(TotalNumberofParticles): 
     UpdateParameters() 
     s='%8.3e %8.3e %8.3e %8.3e %8.3e %8.3e %8.3e %8.3e %8.3e %8.3e %8.3e %8.3e %8.3e\t\t'%(xpos1[i],ypos1[i],zpos1[i],xvel1[i],yvel1[i],zvel1[i],xacc1[i],yacc1[i],zacc1[i],xforc[i],yforc[i],zforc[i],potn[i]) 
     f.write(s) 
     ... 
    s='%8.3e %8.3e %8.3e\n'%(KE,PE,TE)  
    f.write(s) 
    t=t+delt 
f.close() 

Also, wenn es 500 Teilchen, jede Zeile in der Datendatei wird 7000 Spalten haben. Es scheint irgendwie eine schlechte Art, Daten zu speichern. Außerdem läuft die Simulation für mehrere tausend Zeitschritte. Wenn das Programm fortschreitet, wird es auch langsamer. Kann mir jemand eine Idee geben, wie ich meine Daten besser speichern kann? Ich würde auch gerne wissen, wie ich diese Daten für weitere Analysen abrufen kann.

Antwort

3

Anstatt jeden xpos[i] separat in einer Schleife zu schreiben, schreiben Sie das gesamte Array in einem mit numpy.savez gehen;

import numpy as np 

np.savez('myMD.dat', 
     xpos1=xpos1, ypos1=ypos1, zpos1=zpos1, 
     xvel1=xvel1, yvel1=yvel1, zvel1=zvel1, 
     xacc1=xacc1, yacc1=yacc1, zacc1=zacc1, 
     xforc=xforc, yforc=yforc, zforc=zforc, 
     potn=potn) 

Mit Schlüsselwörtern wie dieser wird sichergestellt, dass die Arrays mit ihrem richtigen Namen gespeichert werden.

Da Sie das Datum für jedes Partikel und für jede Iteration schreiben möchten, schlage ich vor, dass Sie den Arrays eine zusätzliche Achse hinzufügen, die alle Iterationen enthält.

Also statt

xpos1 = np.array(TotalNumberofParticles) 

tun

xpos1 = np.array((number_of_iterations, TotalNumberofParticles)) 

Sie numpy.load verwenden können, um die Daten wieder zu lesen:

import numpy as np 

data = numpy.load('myMD.dat') 
xpos1 = data['xpos1'] 
# et cetera 

BTW, von PEP 8 (der Python Style Guide):

Wildcard-Importe (from <module> import *) sollten vermieden werden, da es unklar ist, welche Namen im Namespace vorhanden sind, was sowohl Leser als auch viele automatisierte Tools verwirrt.

+0

Ich habe nur eine Abfrage mit 'np.savez ('myMD.dat', xpos1 = xpos1, ypos1 = ypos1, ..., zforc = zforc, potn = potn)'. Kann ich diese Zeile innerhalb einer Schleife schreiben, da Daten für xpos1, ypos1 usw. für alle Partikel aufgezeichnet werden sollen. Und wenn ja, kann ich jeweils den gleichen Keyword-Namen angeben? – kanayamalakar

+0

@kanayamalakar Ich nehme an, Sie meinen, Sie möchten Daten für alle Partikel und alle Zeitschritte aufzeichnen? Ich habe meine Antwort geändert, um das zu reflektieren. –

1

Sie Gurke verwenden können beliebige Daten zu schreiben und zu lesen:

import pickle 

a= [4,6,3,7,] 

f=open("testfile", "wb") 
pickle.dump(a,f) 
f.close() 

f=open("testfile", "rb") 
b=pickle.load(f) 
f.close() 

print b