2010-11-15 56 views
0

好的。我在Matlab中有一些背景,現在我正在切換到Python。 我有64位Linux Pythnon 2.6.5下此位的代碼,通過目錄滾動,找到名爲「GeneralData.dat」的文件,從中獲取一些數據,並將其縫合成一個新的數據集:使用os.path.walk時賦值前賦值的問題

import pylab as p 
import os, re 
import linecache as ln 

def LoadGenomeMeanSize(arg, dirname, files): 
     for file in files: 
      filepath = os.path.join(dirname, file) 
      if filepath == os.path.join(dirname,'GeneralData.dat'): 
       data = p.genfromtxt(filepath) 
       if data[-1,4] != 0.0: # checking if data set is OK 
        data_chopped = data[1000:-1,:] # removing some of data 
        Grand_mean = data_chopped[:,2].mean() 
        Grand_STD = p.sqrt((sum(data_chopped[:,4]*data_chopped[:,3]**2) + sum((data_chopped[:,2]-Grand_mean)**2))/sum(data_chopped[:,4])) 
       else: 
        break 
      if filepath == os.path.join(dirname,'ModelParams.dat'): 
       l = re.split(" ", ln.getline(filepath, 6)) 
       turb_param = float(l[2])     
       arg.append((Grand_mean, Grand_STD, turb_param)) 

GrandMeansData = [] 
os.path.walk(os.getcwd(), LoadGenomeMeanSize, GrandMeansData) 
GrandMeansData = sorted(GrandMeansData, key=lambda data_sort: data_sort[2]) 

TheMeans = p.zeros((len(GrandMeansData), 3)) 
i = 0 
for item in GrandMeansData: 
    TheMeans[i,0] = item[0] 
    TheMeans[i,1] = item[1] 
    TheMeans[i,2] = item[2] 
    i += 1 

print TheMeans # just checking... 
# later do some computation on TheMeans in NumPy 

它拋出我這個(儘管我發誓這是工作一個月自負):

Traceback (most recent call last): 
    File "/home/User/01_PyScripts/TESTtest.py", line 29, in <module> 
    os.path.walk(os.getcwd(), LoadGenomeMeanSize, GrandMeansData) 
    File "/usr/lib/python2.6/posixpath.py", line 233, in walk 
    walk(name, func, arg) 
    File "/usr/lib/python2.6/posixpath.py", line 225, in walk 
    func(arg, top, names) 
    File "/home/User/01_PyScripts/TESTtest.py", line 26, in LoadGenomeMeanSize 
    arg.append((Grand_mean, Grand_STD, turb_param)) 
UnboundLocalError: local variable 'Grand_mean' referenced before assignment 

好吧......讓我去,做一些閱讀,並與這個全局變量想出了:

import pylab as p 
import os, re 
import linecache as ln 

Grand_mean = p.nan 
Grand_STD = p.nan 
def LoadGenomeMeanSize(arg, dirname, files): 
     for file in files: 
      global Grand_mean 
      global Grand_STD 
      filepath = os.path.join(dirname, file) 
      if filepath == os.path.join(dirname,'GeneralData.dat'): 
       data = p.genfromtxt(filepath) 
       if data[-1,4] != 0.0: # checking if data set is OK 
        data_chopped = data[1000:-1,:] # removing some of data 
        Grand_mean = data_chopped[:,2].mean() 
        Grand_STD = p.sqrt((sum(data_chopped[:,4]*data_chopped[:,3]**2) + sum((data_chopped[:,2]-Grand_mean)**2))/sum(data_chopped[:,4])) 
       else: 
        break 
      if filepath == os.path.join(dirname,'ModelParams.dat'): 
       l = re.split(" ", ln.getline(filepath, 6)) 
       turb_param = float(l[2])     
       arg.append((Grand_mean, Grand_STD, turb_param)) 

GrandMeansData = [] 
os.path.walk(os.getcwd(), LoadGenomeMeanSize, GrandMeansData) 
GrandMeansData = sorted(GrandMeansData, key=lambda data_sort: data_sort[2]) 

TheMeans = p.zeros((len(GrandMeansData), 3)) 
i = 0 
for item in GrandMeansData: 
    TheMeans[i,0] = item[0] 
    TheMeans[i,1] = item[1] 
    TheMeans[i,2] = item[2] 
    i += 1 

print TheMeans # just checking... 
# later do some computation on TheMeans in NumPy 

它不會給錯誤按摩。甚至給數據文件...但數據是血腥的錯誤!我通過運行命令手動檢查了其中的一些:

import pylab as p 
data = p.genfromtxt(filepath) 
data_chopped = data[1000:-1,:] 
Grand_mean = data_chopped[:,2].mean() 
Grand_STD = p.sqrt((sum(data_chopped[:,4]*data_chopped[:,3]**2) \ 
+ sum((data_chopped[:,2]-Grand_mean)**2))/sum(data_chopped[:,4])) 

對選定的文件。他們是不同的:-(

1)任何人都可以解釋我有什麼不對?

2)有誰知道解決方案嗎?

我會幫忙:-)

乾杯感謝, PTR

回答

0

我要說的這個條件是不及格: if filepath == os.path.join(dirname,'GeneralData.dat'):

,這意味着你沒有得到GeneralData.dat在ModelParams.dat之前。也許你需要按字母順序排序或者文件不存在。

+0

盆景!謝謝馬特! – PTR 2010-11-15 17:29:30

+0

請考慮通過點擊旁邊的複選框給我的答案:) – 2010-11-16 16:05:48

0

我看到您提供的代碼和解決方案有一個問題。

通過只顯示變量,永遠不要隱藏「賦值前變量引用」的問題。 試着瞭解它爲什麼發生?

在創建一個全局變量「Grand_mean」之前,你得到一個問題,你在訪問Grand_mean之前給它賦值。在這種情況下,通過初始化函數外的變量並將其標記爲全局變量,僅用於隱藏問題。

您會看到錯誤的結果,因爲現在您已將該變量顯示爲全局變量,但問題仍然存在。你Grand_mean從未被平等化爲一些正確的數據。

這意味着,「如果文件路徑== os.path.join(目錄名,...」從未執行。

+1

社區的眼睛在工作:-) 乾杯!這是問題所在。固定! – PTR 2010-11-15 17:30:29

+0

@PTR:歡呼聲。事實上,我們都在一路上學習。我瞭解到,通過全局變量跳過先前引用的問題使得查看錯誤結果變得更加困難。 – pyfunc 2010-11-15 17:36:42

0

使用全局不正確的解決方案,那纔有意義,如果下的代碼段中,確實需要參考和分配全球「Grand_mean」的名稱,需要消除歧義的方式來自於解釋者在函數聲明中對賦值運算符進行預分析的方式

您應該首先將缺省值分配給Grand_mean範圍爲LoadGenomeMeanSize()。你有4個分支中的1個實際上爲一個循環迭代中具有正確語義含義的Grand_mean賦值。你很可能運行到哪裏

if filepath == os.path.join(dirname,'ModelParams.dat'):是真實的情況,但無論哪種 if filepath == os.path.join(dirname,'GeneralData.dat'):if data[-1,4] != 0.0:不是。這可能是你失敗的第二個條件。移動

的快速和骯髒的答案是,你可能需要重新安排你的代碼是這樣的:

... 
      if filepath == os.path.join(dirname,'GeneralData.dat'): 
       data = p.genfromtxt(filepath) 
       if data[-1,4] != 0.0: # checking if data set is OK 
        data_chopped = data[1000:-1,:] # removing some of data 
        Grand_mean = data_chopped[:,2].mean() 
        Grand_STD = p.sqrt((sum(data_chopped[:,4]*data_chopped[:,3]**2) + sum((data_chopped[:,2]-Grand_mean)**2))/sum(data_chopped[:,4])) 

        if filepath == os.path.join(dirname,'ModelParams.dat'): 
         l = re.split(" ", ln.getline(filepath, 6)) 
         turb_param = float(l[2])     
         arg.append((Grand_mean, Grand_STD, turb_param)) 
       else: 
        break 

... 
+0

都能跟得上...然後GrandMeansData(os.path.walk寫入一個)是一個空數組... 但是,如果你知道什麼時候GeneralData.dat存在andvise反之亦然(這就是而言)ModelParams.dat始終存在,那麼你可以創建一個新的文件路徑,比如說filepath_two並在其中存儲有關ModelParams.dat位置的信息。這就是我所做的。 – PTR 2010-11-15 17:40:02

+0

原因是什麼,我相信,是因爲當條件文件路徑== os.path.join(目錄名稱,「GeneralData.dat」)爲真,則(嵌套在它)文件路徑== os.path.join(目錄名稱」 ModelParams.dat')不能默認和arg.append((Grand_mean,Grand_STD,turb_param))的休耕不執行正確的。 但是,謝謝傑里米!無論如何我都試過:-) – PTR 2010-11-15 17:52:52