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

Pie*_*olo 9 python numpy python-2.7

我想在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
Run Code Online (Sandbox Code Playgroud)
  • 每个部分都有一组由第一行给出的变量.当一个部分结束时,一个新部分以两条相似的行开头.
  • 对于每个变量,都有I*J*K值.
  • 每个变量都是一个连续的值块.
  • 每行有固定数量的值(6).
  • 变量结束时,下一个变量以新行开头.
  • 变量是"IJK有序数据".I指数变化最快; J指数下一个最快; K指数最慢.I-index应该是内部循环,K-index应该是外部循环,而J-index应该是循环之间的循环.

以下是数据示例:

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
Run Code Online (Sandbox Code Playgroud)

我是python的新手,我编写了一个代码将数据导入字典,将变量写为3D numpy.array.这些文件可能非常大(最高为Gb).如何让这段代码更快?(或者更一般地说,如何尽可能快地导入这些文件)?

import re
from numpy import zeros, array, prod
def vectorr(I,  J,  K):
    """function"""
    vect = []
    for k in range(0,  K):
        for j in range(0, J):
            for i in range(0, I):
                vect.append([i, j, k])
    return vect

a = open('E:\u.dat')

filelist = a.readlines()

NumberCol = 6
count = 0
data = dict()
leng = len(filelist)
countzone = 0
while count < leng:
    strVARIABLES = re.findall('VARIABLES', filelist[count])
    variables = re.findall(r'"(.*?)"',  filelist[count])
    countzone = countzone+1
    data[countzone] = {key:[] for key in variables}
    count = count+1
    strI = re.findall('I=....', filelist[count])
    strI = re.findall('\d+', strI[0]) 
    I = int(strI[0])
    ##
    strJ = re.findall('J=....', filelist[count])
    strJ = re.findall('\d+', strJ[0])
    J = int(strJ[0])
    ##
    strK = re.findall('K=....', filelist[count])
    strK = re.findall('\d+', strK[0])
    K = int(strK[0])
    data[countzone]['indmax'] = array([I, J, K])
    pr = prod(data[countzone]['indmax'])
    lin = pr // NumberCol
    if pr%NumberCol != 0:
        lin = lin+1
    vect = vectorr(I, J, K)
    for key in variables:
        init = zeros((I, J, K))
        for ii in range(0, lin):
            count = count+1
            temp = map(float, filelist[count].split())
            for iii in range(0, len(temp)):
                init.itemset(tuple(vect[ii*6+iii]), temp[iii])
        data[countzone][key] = init
    count = count+1
Run Code Online (Sandbox Code Playgroud)

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

vir*_*obi 0

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

  • 编译更常用的 RE(我猜这适用于您示例中的所有 RE)。对它们执行操作regex=re.compile("<pattern>"),并将生成的对象与 一起使用match=regex.match(),如Python 文档中所述。

  • 对于 I、J、K RE,考虑使用分组功能(如上所述)将两个 RE 减少为一个,方法是搜索“I=(\d+)”形式的模式,并抓取其中匹配的部分括号中使用regex.group(1). 更进一步,您可以定义一个正则表达式来一步捕获所有三个变量。

至少对于开始这些部分来说,RE 似乎有点矫枉过正:您需要查找的字符串没有变化,并且string.find()在这种情况下就足够了,而且可能更快。

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