2012-05-03 52 views
0

我對Python很新穎,我正在編寫一個程序,它將執行從.txt文件中讀取數據並請求用戶信息的4點線性插值。Python中的線性插值

.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

既然是空白在Python中有重要意義,請確保在粘貼代碼時保留原始縮進。 – huon

回答

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(來自Python 2.x中的range(...))中創建list是完全沒有必要的。一個更好的「手動」替代你的代碼將

    for i in xrange(len(filename)): 
    

    ,但它仍然比上面的成語可讀的要少得多。

現在我做撲在你的代碼,主要的問題是:什麼[地獄]實際上,你需要做什麼?你能否給我們準確的,逐字的,你正試圖解決的問題的規範?

  • 你看了看http://en.wikipedia.org/wiki/Linear_interpolation
  • 你的情況下終端輸入數據的意義是什麼?
  • 爲什麼需要來自終端輸入數據前後的文件中的數據?
  • 溫度/壓力數據是否按排序?
  • 文件中的行代表什麼(例如,它們是基於時間的還是基於位置的或其他)?
  • 四種不同壓力代表什麼?
+0

我並不清楚實際的問題陳述。給定溫度和壓力,程序應執行線性插值以找出U(內部能量)。 T值是第一列,P值是第一行,其餘是U值。 我更新了表中的實際值。對不起所有的困惑和感謝您的幫助。 – LC4Tigers

+0

@ LC4Tigers:所以你需要2D插值? –

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

這裏有兩個不同的問題:如何將數據讀入蟒蛇/ NumPy的, 怎麼辦2D interpolatation。
讀取數據,我建議 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 可以很容易地嘗試單線條,看變量...