Python中的线性插值

时间:2012-05-03 04:25:37

标签: python interpolation linear

我对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值。

3 个答案:

答案 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)

  1. 使用.readlines()会在文件变大后立即向你射击。你能否根据

    制定你需要做的事情
    for line in open(...):
        # parse line
    

    并解析文件一次而不将其完全加载到内存中。

    • 更好的是,在处理文件时使用with习语:

      with open(...) as file:
          for line in file:
              # parse line
      

      当使用该文件时出现问题,这可以让您省去一些麻烦。

  2. 如果您最终使用float()从字符串中删除浮点数,则无需删除换行符。 float('1.2 \t\n')是完全有效的代码。

  3. 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)):
    

    但它的可读性仍然低于上述成语。

  4. 现在我已经完成了对你的代码的攻击,主要的问题是:你真的需要做什么?您能否为我们提供您想要解决的问题的准确,逐字逐句的说明?

    • 你看过http://en.wikipedia.org/wiki/Linear_interpolation吗?
    • 您案例中来自终端的输入数据的重要性是什么?
    • 为什么以及为什么需要来自终端输入数据之前和之后的文件中的数据?
    • 温度/压力数据是否以某种方式排序?
    • 文件中的行代表什么(例如,它们是基于时间的还是基于位置的还是其他内容)?
    • 四种不同的压力代表什么?