2016-06-19 10 views
0

Ich habe ein Python-Skript erstellt, wo ich in einer Datei ein Array von V (Volumes) in einer Spalte schreiben:Python [float (n) für n in line.split()] über eine Datei, die nur eine Spalte enthält

import numpy as np 

volume_pressure_energy = open('datafile.dat', 'w') # Open the file, 'w' for writing 
V = np.linspace(62, 72, 5) 
with open('datafile.dat') as volume_pressure_energy: 
    np.savetxt('datafile.dat', V, '%10.9f', delimiter='\t', header=" volume\tpressure\tenergy") 

volume_pressure_energy.close() 

Dies erzeugt diese Datei datafile.dat:

# volume  pressure  energy 
62.000000000 
64.500000000 
67.000000000 
69.500000000 
72.000000000 

die nächsten Zeilen des Skripts versuchen, die pressure und die energy unter Verwendung von Funktionen und Parameter zu berechnen:

# Parameters 
E0 = -9 
B0 = 7 
V0 = 6 
B0_prime = 4 

# Function P(V): 
def P(V): # To use a P(V) is inevitable as the function depends on V 
    f0=(3.0/2.0)*B0 
    f1=((V0/V)**(7.0/3.0))-((V0/V)**(5.0/3.0)) 
    f2=((V0/V)**(2.0/3.0))-1 
    pressure= f0*f1*(1+(3.0/4.0)*(B0_prime-4)*f2) 
    return pressure 

# Function E(V): 
def E(V): 
    E = E0+ (2.293710449E+17)*(1E-21)*((9.0/16.0)*(V0*B0) * ( (((V0/V)** (2.0/3.0)-1)**3)*B0_prime + ((V0/V)**(2.0/3.0)-1)**2 * (6.0-4.0*(V0/V)**(2.0/3.0)) )) 
    return E 

Jetzt möchte ich datafile.dat lesen und behandeln die erste Spalte als volume Daten. Diese volume Daten werden die Funktion P(V) eingeben, und gibt mir pressure. In ähnlicher Weise werden diese volume Daten die Funktion E(V) eingeben und geben mir energy:

with open('datafile.dat') as volume_pressure_energy: # open the file 
    volume_pressure_energy.next() # skip the first line 
    for line in volume_pressure_energy: 
    volume = [float(n) for n in line.split()] # split the lines 
    # (removes linebreaks, tabs and spaces) 
    # convert all items to floats. 
    pressure = P(volume) # call my function 
    energy = E(volume) # call my function 
    volume_pressure_energy.write('{}\t{}\t{}\n'.format(volume, pressure, energy)) 
volume_pressure_energy.close() 

Wenn alle dieses Skript ausgeführt wird (unter denen ich geschrieben habe das komplette Skript), heißt es, dass

Traceback (most recent call last): 
File "BM-model-Enth-obtention_data_E_vs_P.py", line 76, in <module> 
pressure = P(volume) # call your function 
File "BM-model-Enth-obtention_data_E_vs_P.py", line 50, in P 
f1=((V0/V)**(7.0/3.0))-((V0/V)**(5.0/3.0)) 
TypeError: unsupported operand type(s) for /: 'float' and 'list' 

Anscheinend gibt es ein Problem mit den Funktionen. Ich habe sie getrennt laufen und gut funktionieren, so ist das Problem, dass Python nicht davon ausgeht, dass jede Zeile der ersten Spalte von datafile.dat enthält die V, die Volumes, die in den Funktionen eingefügt werden.

Warum passiert das? volume = [float(n) for n in line.split()] teilt die Zeilen auf und konvertiert alle Elemente in Gleitkommazahlen. Warum sollte das also das Problem sein?

komplette Skript:

import numpy as np 

volume_pressure_energy = open('datafile.dat', 'w') # Open the file, 'w' for writing 
V = np.linspace(62, 72, 5) 
with open('datafile.dat') as volume_pressure_energy: 
    np.savetxt('datafile.dat', V, '%10.9f', delimiter='\t', header=" volume\tpressure\tenergy") 

volume_pressure_energy.close() 

# Parameters 
E0 = -9 
B0 = 7 
V0 = 6 
B0_prime = 4 

# Function P(V): 
    def P(V): # To use a P(V) is inevitable as the function depends on V 
    f0=(3.0/2.0)*B0 
    f1=((V0/V)**(7.0/3.0))-((V0/V)**(5.0/3.0)) 
    f2=((V0/V)**(2.0/3.0))-1 
    pressure= f0*f1*(1+(3.0/4.0)*(B0_prime-4)*f2) 
    return pressure 

# Function E(V): 
    def E(V): 
    E = E0+ (2.293710449E+17)*(1E-21)*((9.0/16.0)*(V0*B0) * ( (((V0/V)** (2.0/3.0)-1)**3)*B0_prime + ((V0/V)**(2.0/3.0)-1)**2 * (6.0-4.0*(V0/V)**(2.0/3.0)) )) 
    return E 

with open('datafile.dat') as volume_pressure_energy: # open the file 
volume_pressure_energy.next() # skip the first line 
for line in volume_pressure_energy: 
    volume = [float(n) for n in line.split()] # split the lines 
    # (removes linebreaks, tabs and spaces) 
    # convert all items to floats. 
    pressure = P(volume) # call my function 
    energy = E(volume) # call my function 
    volume_pressure_energy.write('{}\t{}\t{}\n'.format(volume, pressure, energy)) 
volume_pressure_energy.close() 
+1

'volume = float (line.split() [0])'. 'str.split()' gibt eine Liste zurück, auch wenn es nur ein Element ist. Sie sollten also das erste (und einzige) Element erhalten, indem Sie auf den Index '[0]' zugreifen. – Mephy

Antwort

1

Wenn es nur eine Nummer auf jeder Zeile sein wird, dann sollte

volume = float(line) 

line.split tun Sie zu lesen() gibt eine Liste mit einem einzelnen Element in dieser Zeile die Zeichenfolge enthält . Also, wenn Sie tun

volume = [float(n) for n in line.split()] 

Sie sagen, dass Sie eine Liste wollen, dass jedes Element von line.split enthält() umgewandelt zu einem Schwimmer.

Und das ist, was der Fehler sagt. Das Volumen ist eine Liste. Und Sie können eine Nummer nicht durch eine Liste teilen. Wenn es mehrere Nummern in derselben Zeile geben könnte und Sie die erste möchten. Dann sollten Sie das 0. Element des Volumens an die Funktionen zur Berechnung des Druckes usw. übergeben.

+0

+1, Danke für Ihren Kommentar. Ich habe 'volume = [float (n) für n in line.split()]' durch 'volume = float (line)' ersetzt, und der ganze Rest des Codes ist gleich. Aber ich erhalte diesen Fehler: 'Traceback (letzter Anruf zuletzt): Datei" BM-model-Enth-obtention_data_E_vs_P.py ", Zeile 81, in volume_pressure_energy.write ('{} \ t {} \ t {} \ n'.format (Volumen, Druck, Energie)) IOError: Datei zum Schreiben nicht geöffnet. Es sollte zum Schreiben verfügbar sein, da ich in der zweiten Zeile "w" deklariert habe. –

+1

Sie schließen die Datei und öffnen sie erneut die for-Schleife, @DavidC. Beim zweiten Mal öffnen Sie es nicht zum Schreiben. –

1

Sie jede Zeile Aufspalten und das Bestehen der Liste Verständnis (eine Liste) statt der Zahl, Schwimmer, dass Sie die Methoden vorbei sein sollte.

Ich denke, was Sie tun möchten, ist:

volume = [float(n) for n in line.split()][0] 

die weiter vereinfacht werden könnte, um nicht alle Elemente des geteilten als Schwimmer behandeln zu float(line.split()[0])

+0

Warum der Downvote? Ich bin damit fertig ... –

+1

+1, weil dies eine richtige Antwort ist und es nervt, wenn Leute keinen Kommentar für einen Downvote hinterlassen. – Nicarus

+0

@ JuanCortés Danke für deinen Kommentar –

1

Der Fehler ist Ihnen zu sagen, dass Sie‘ t dividiere eine ganze Zahl durch eine Liste. Ich vermute, du verwirrst Listen und Nummernfelder. Vielleicht können Sie die Liste in ein Array mit etwas wie asarray() konvertieren.

>>> import numpy as np 
>>> l = [2.0, 3.0, 4.0] 
>>> 1/l 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unsupported operand type(s) for /: 'int' and 'list' 
>>> a = np.asarray(l) 
>>> 1/a 
array([ 0.5  , 0.33333333, 0.25  ]) 
+0

'V = np.linspace (62, 72, 5)' gibt 'V' zurück, das ist schon ein Array, keine Liste. 'ipython; import numpy als np; V = np.linspace (62, 72, 5); V; Array ([62., 64.5, 67., 69.5, 72.]) ' –

1

Eine vielseitige Lösung ist die Verwendung numpy.fromfile. Es handhabt Binärdateien und liest sie direkt in ein ndarray.

volume_pressure_energy = np.fromfile('datafile.dat',dtype=float) 

Weitere Informationen finden Sie in der Dokumentation.

+0

Danke für Ihren Kommentar –