2010-11-15 68 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