【发布时间】:2013-10-06 18:37:07
【问题描述】:
我想在 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-index 变化最快; J-index 次之; 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
我是 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
附言。在python中,没有cython或其他语言
【问题讨论】:
-
首先将
a = open('E:\8-Documenti\onera stage\u.dat')更改为with open('E:\8-Documenti\onera stage\u.dat') as a。其次,您的代码似乎还可以,看不到任何引人注目的东西会使它变得非常慢。 PS: tu fais un stage dans onera? ;) -
使用 RunSnakeRun 来分析你的代码,以便知道时间花在了哪里。我认为大文件上的正则表达式不是一个好主意。尝试改用 PEG?还是一些自定义解析?
-
嗯,我不知道你在说什么:-)。自定义解析?
-
你的电脑有多少内存?如果事情变得非常缓慢,您可能会耗尽所有内存(第一个 f.readlines() 调用会将所有内容读取到内存中,并且您的 Numpy 数据结构可能会占用同样多的内存)。从文件格式的外观来看,您可以按顺序读取它,而无需将所有内容复制到 RAM。就像 mguijarr 建议的那样,分析您的代码以找出导致它变慢的原因。
-
为什么你有几个 Gb 大小的 ascii 文件?如果它们以二进制格式(.fits 或类似格式)存储,它们会运行得更快
标签: python python-2.7 numpy