Python [float(n) for n in line.split()] 在只包含一列的文件上

Python [float(n) for n in line.split()] over a file that contains only one column

我创建了一个 python 脚本,我在文件中的一列中写入了一个 V(卷)数组:

 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()

这会生成此文件 datafile.dat :

 #  volume       pressure        energy
 62.000000000
 64.500000000
 67.000000000
 69.500000000
 72.000000000

脚本的下一行尝试使用函数和参数计算 pressureenergy

# 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

现在,我想读取 datafile.dat 并将第一列视为 volume 数据。这个volume数据会进入函数P(V),会给我pressure。同样,这个volume数据会进入函数E(V),会给我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()

当运行所有这些脚本(下面我已经发布了完整的脚本)时,它说

 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'

很明显,功能有问题。我已经单独运行它们并且工作正常,所以问题是 python 没有假设 datafile.dat 第一列的每一行包含 V,插入的卷函数。

为什么会这样? volume = [float(n) for n in line.split()] 正在拆分行并将所有项目转换为浮点数,那么为什么这会是问题所在?

完整脚本:

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()

您要拆分每一行并传递列表理解(列表)而不是您应该传递给方法的数字浮点数。

我想你想做的是:

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

这可以进一步简化为不将拆分的所有元素都视为 float(line.split()[0])

的浮点数

错误提示您不能将整数除以列表。我怀疑您混淆了列表和 numpy 数组。也许您可以使用 asarray().

之类的方法将列表转换为数组
>>> 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      ])

如果每一行只有一个数字,那么阅读你应该这样做

volume = float(line)

line.split() returns 一个包含单个元素的列表,该元素包含该行上的字符串。所以当你这样做时

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

你是说你想要一个列表,其中包含 line.split() 的每个元素转换为浮点数。

这就是错误的意思。 volume 是一个列表。你不能用一个列表来除一个数字。 如果同一行可能有多个数字,而您想要第一个。然后你应该将体积的第0个元素传递给计算压力等函数

更通用的解决方案是使用 numpy.fromfile。它处理二进制文件并将其直接读取到 ndarray。

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

有关更多信息,请参阅文档。