Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
尽可能快地在python中导入大型tecplot块文件_Python_Python 2.7_Numpy - Fatal编程技术网

尽可能快地在python中导入大型tecplot块文件

尽可能快地在python中导入大型tecplot块文件,python,python-2.7,numpy,Python,Python 2.7,Numpy,我想在python中导入一些ascii文件(来自tecplot,cfd后处理软件)。 这些文件的规则是(至少对于我需要导入的文件): 该文件分为几个部分 每个部分有两行作为标题,如: VARIABLES = "x" "y" "z" "ro" "rovx" "rovy" "rovz" "roE" "M" "p" "Pi" "tsta" "tgen" ZONE T="Window(s) : E_W_Block0002_ALL", I=29, J=17, K=25, F=BLOCK 每

我想在python中导入一些ascii文件(来自tecplot,cfd后处理软件)。 这些文件的规则是(至少对于我需要导入的文件):

  • 该文件分为几个部分
每个部分有两行作为标题,如:

VARIABLES = "x" "y" "z" "ro" "rovx" "rovy" "rovz" "roE" "M" "p" "Pi" "tsta" "tgen" 
ZONE T="Window(s) : E_W_Block0002_ALL",  I=29,  J=17,  K=25, F=BLOCK
  • 每个部分都有一组由第一行给出的变量。当一个区段结束时,一个新区段以两条相似的线开始
  • 每个变量都有I*J*K值
  • 每个变量都是一个连续的值块
  • 每行有固定数量的值(6)
  • 当一个变量结束时,下一个变量在新行中开始
  • 变量为“IJK有序数据”。I指数变化最快;第二快的是J指数;K指数是最慢的。I指数应该是内环,K指数应该是外环,J指数应该是中间的环
以下是一个数据示例:

VARIABLES = "x" "y" "z" "ro" "rovx" "rovy" "rovz" "roE" "M" "p" "Pi" "tsta" "tgen" 
ZONE T="Window(s) : E_W_Block0002_ALL",  I=29,  J=17,  K=25, F=BLOCK
-3.9999999E+00 -3.3327306E+00 -2.7760824E+00 -2.3117116E+00 -1.9243209E+00 -1.6011492E+00
[...]
0.0000000E+00 #fin first variable
-4.3532482E-02 -4.3584235E-02 -4.3627592E-02 -4.3663762E-02 -4.3693815E-02 -4.3718831E-02 #second variable, 'y'
[...]
1.0738781E-01 #end of second variable
[...]
[...]
VARIABLES = "x" "y" "z" "ro" "rovx" "rovy" "rovz" "roE" "M" "p" "Pi" "tsta" "tgen" #next zone
ZONE T="Window(s) : E_W_Block0003_ALL",  I=17,  J=17,  K=25, F=BLOCK
我是python新手,我编写了一段代码将数据导入字典,将变量写成3D
numpy.array
。这些文件可能非常大(高达Gb)。如何使代码更快?(或者更一般地说,如何尽可能快地导入此类文件)

重新导入
从numpy导入零、数组、产品
def矢量器(I,J,K):
“功能”
vect=[]
对于范围(0,k)内的k:
对于范围(0,j)内的j:
对于范围(0,i)中的i:
向量附加([i,j,k])
返回向量
a=打开('E:\u.dat')
filelist=a.readlines()
NumberCol=6
计数=0
数据=dict()
leng=len(文件列表)
countzone=0
当计数

在python中,没有cython或其他语言

如果您在这里使用正则表达式,有两件事我会改变:

  • 编译使用频率更高的REs(我想这适用于示例中的所有REs)。对它们执行
    regex=re.compile(“”)
    ,并将结果对象与
    match=regex.match()
    一起使用,如中所述

  • < i > j,K REs,考虑减少两个RE到一个,使用分组特征(上面也描述),通过搜索形式“i=(\d+)”,并使用<代码>正则表达式(组)(1)< /代码>获取括号内匹配的部分。进一步说,您可以定义一个正则表达式,在一个步骤中捕获所有三个变量

至少在开始部分时,REs似乎有点过分:您需要查找的字符串中没有变化,
string.find()
在这种情况下就足够了,而且可能更快


编辑:我刚刚看到您已经对变量使用了分组…

将大量字符串转换为数字总是有点慢,但是假设三重嵌套for循环是这里的瓶颈,那么将其更改为以下值可能会给您带来足够的加速:

# add this line to your imports
from numpy import fromstring

# replace the nested for-loop with:
count += 1
for key in variables:
    str_vector = ' '.join(filelist[count:count+lin])
    ar = fromstring(str_vector, sep=' ')
    ar = ar.reshape((I, J, K), order='F')

    data[countzone][key] = ar 
    count += lin
不幸的是,目前我只能访问我的智能手机(没有pc),所以我无法测试它的速度,甚至无法测试它是否正常工作


更新

最后,我开始做一些测试:

  • 我的代码中有一个小错误,但它现在似乎工作正常
  • 修改后的代码运行速度大约是原来的4倍
  • 您的代码大部分时间都花在
    ndarray.itemset
    上,可能还有循环开销和浮点转换。不幸的是,cProfile没有详细显示这一点
  • 改进后的代码在
    numpy.fromstring
    中花费了大约70%的时间,在我看来,这表明对于使用Python/numpy可以实现的功能来说,这种方法相当快

更新2


当然,更好的方法是迭代文件,而不是一次加载所有内容。在这种情况下,这稍微快一点(我试过了),并显著减少了内存使用。您也可以尝试使用多个CPU核来加载和转换浮点,但这样就很难将所有数据放在一个变量下。最后一个警告:我使用的
fromstring
方法对字符串长度的缩放效果相当差。例如,从某个字符串长度开始,将
np.fromiter(itertools.imap(float,str\u vector.split()),dtype=float)之类的东西作为

a=open('E:\8-Documenti\onera stage\u.dat')
更改为
以open('E:\8-Documenti\onera stage\u.dat')开头。其次,你的代码看起来还行,看不到任何引人注目的东西,这会使它变得非常缓慢。PS:tu fais un stage dans onera?;)使用RunSnakeRun分析代码,以便知道时间花在哪里。我认为在大文件上使用正则表达式不是一个好主意。试着用PEG代替?或者一些自定义解析?嗯,我不知道你在说什么
# add this line to your imports
from numpy import fromstring

# replace the nested for-loop with:
count += 1
for key in variables:
    str_vector = ' '.join(filelist[count:count+lin])
    ar = fromstring(str_vector, sep=' ')
    ar = ar.reshape((I, J, K), order='F')

    data[countzone][key] = ar 
    count += lin