我对Python很陌生,我正在尝试编写一个程序,该程序将从.txt文件读取数据并询问用户信息。
.txt文件在表格中具有以下格式的温度和压力:
T P1 P2 P3 P4
80,100,150,200
75, 400,405,415,430
100, 450,456,467,483
150, 500,507,519,536
200, 550,558,571,589
这是代码:
# User input
temp = input("Enter temperature value in degrees Celcius [Range: 75-200]:")
pressure = input("Enter pressure value in bars [Range: 80-589")
temp = float(temp)
pressure = float(pressure)
# Opens file and read data
filename = open('xxxxxxxxxxxxx.txt', 'r').readlines()
# Removes \n from each line
for i in list(range((len(filename)-1))):
filename[i] = filename[i][:-1]
# Splits string
for i in list(range(len(filename))):
filename[i] = filename[i].split(',')
# Converts string numbers into decimal numbers
for i in [2,3,4,5,6]:
filename[i][0] = float(filename[i][0])
filename[i][1] = float(filename[i][1])
我不知道从哪里开始。如果用户输入是,T = 100且P = 200,我如何找到文件中直接在这些数字之前和之后的数据点?
显然,我对我正在做的事情知之甚少,但我会感激任何帮助。
ETA:实际表格值。 另外,我不清楚实际的问题陈述。给定温度和压力,程序应执行线性插值以找到U(内部能量)。 T值是第一列,P值是第一行,其余是U值。
答案 0 :(得分:1)
假设您有一个已排序的数字列表x1, x2, x3... xn
,您可以使用bisect
模块快速定位所需的时间间隔(O(log n)
)
from bisect import bisect, bisect_right, bisect_left
# 0 1 2 3 4 5 6 7
x = [1, 2, 4, 8, 16, 100, 200, 300]
def find_interval(x,y):
# x must be a sorted list.
index = bisect_left(x,y)
# Larger than largest element in x
if index >= len(x):
l,r = -1, None
# Exactly equal to something in x
elif y == x[index]:
l,r = index, index
# Smaller than smallest element in x
elif index == 0:
l,r = None, 0
# Inbetween two elements in x
else:
l,r = index-1, index
print (x[l] if l != None else "To left of all elements")
print (x[r] if r != None else "To right of all elements")
return (l,r)
>>> x
[1, 2, 4, 8, 16, 100, 200, 300]
>>> find_interval(x,0)
To left of all elements
1
>>> find_interval(x,1000)
300
To right of all elements
>>> find_interval(x,100)
100
100
>>> find_interval(x,12)
8
16
>>>
答案 1 :(得分:1)
这里有两个不同的问题:如何将数据读入python / NumPy,
以及如何进行二维插值
对于阅读数据,我建议
numpy loadtxt,
和插值,
scipy BivariateSpline。
(他们都有比你需要的更多的选择。)
from __future__ import division
from cStringIO import StringIO
import numpy as np
from scipy.interpolate import RectBivariateSpline
np.set_printoptions( 1, threshold=100, edgeitems=10, suppress=True )
# a file inline, for testing --
myfile = StringIO( """
# T P1 P2 P3 P4
0, 80,100,150,200
75, 400,405,415,430
100, 450,456,467,483
150, 500,507,519,536
200, 550,558,571,589
""" )
# file -> numpy array --
# (all rows must have the same number of columns)
TPU = np.loadtxt( myfile, delimiter="," )
P = TPU[0,1:] # top row
T = TPU[ 1:,0] # left col
U = TPU[1:,1:] # 4 x 4, 400 .. 589
print "T:", T
print "P:", P
print "U:", U
interpolator = RectBivariateSpline( T, P, U, kx=1, ky=1 ) # 1 bilinear, 3 spline
# try some t, p --
for t, p in (
(75, 80),
(75, 200),
(87.5, 90),
(200, 80),
(200, 90),
):
u = interpolator( t, p )
print "t %5.1f p %5.1f -> u %5.1f" % (t, p, u)
顺便说一句,对于交互式python, IPython 可以轻松尝试单行,查看变量......
答案 2 :(得分:0)
使用.readlines()
会在文件变大后立即向你射击。你能否根据
for line in open(...):
# parse line
并解析文件一次而不将其完全加载到内存中。
更好的是,在处理文件时使用with
习语:
with open(...) as file:
for line in file:
# parse line
当使用该文件时出现问题,这可以让您省去一些麻烦。
如果您最终使用float()
从字符串中删除浮点数,则无需删除换行符。 float('1.2 \t\n')
是完全有效的代码。
for i in list(range(len(filename))):
这是糟糕的风格。迭代列表的Python习语是
for element in list:
如果您需要列表中的索引,那么您应该使用
for i, element in enumerate(list):
您的方法是“手动的”并且它可以工作,但是在list
中创建list
(来自python 2.x中的range(...)
)是完全没有必要的。代码的更好“手动”替代方案是
for i in xrange(len(filename)):
但它的可读性仍然低于上述成语。
现在我已经完成了对你的代码的攻击,主要的问题是:你真的需要做什么?您能否为我们提供您想要解决的问题的准确,逐字逐句的说明?