【问题标题】:Convert Tecplot ascii to Python numpy将 Tecplot ascii 转换为 Python numpy
【发布时间】:2016-12-24 10:04:33
【问题描述】:

我想将一个 Tecplot 文件转换成一个数组,但我不知道该怎么做。 这是文件的摘录:

TITLE = "Test"
VARIABLES = "x" "y"
ZONE I=18,  F=BLOCK
0.1294538E-01  0.1299554E-01  0.1303974E-01  0.1311453E-01  0.1313446E-01  0.1319080E-01
0.1322709E-01  0.1323904E-01  0.1331753E-01  0.1335821E-01  0.1340850E-01  0.1347061E-01
0.1350522E-01  0.1358302E-01  0.1359585E-01  0.1363086E-01  0.1368307E-01  0.1370017E-01
0.1377368E-01  0.1381353E-01  0.1386420E-01  0.1391916E-01  0.1395847E-01  0.1400548E-01
0.1405659E-01  0.1410006E-01  0.1417611E-01  0.1419149E-01  0.1420015E-01  0.1428019E-01
0.1434745E-01  0.1436735E-01  0.1439856E-01  0.1445430E-01  0.1448778E-01  0.1454278E-01

我想检索 xy 作为数组。所以x 应该包含:

0.1294538E-01  0.1299554E-01  0.1303974E-01  0.1311453E-01  0.1313446E-01  0.1319080E-01
0.1322709E-01  0.1323904E-01  0.1331753E-01  0.1335821E-01  0.1340850E-01  0.1347061E-01
0.1350522E-01  0.1358302E-01  0.1359585E-01  0.1363086E-01  0.1368307E-01  0.1370017E-01

y 应该包含:

0.1377368E-01  0.1381353E-01  0.1386420E-01  0.1391916E-01  0.1395847E-01  0.1400548E-01
0.1405659E-01  0.1410006E-01  0.1417611E-01  0.1419149E-01  0.1420015E-01  0.1428019E-01
0.1434745E-01  0.1436735E-01  0.1439856E-01  0.1445430E-01  0.1448778E-01  0.1454278E-01

我见过np.loadtxt('./file.dat', skiprows=3),但我找不到正确的选项来读取所有数字并分隔每 18 个数字。

另外,我没有运气就开始了这样的事情:

with open(file, 'r') as a:
    for line in a.readlines():
        A = re.match(r'TITLE = (.*$)', line, re.M | re.I)
        B = re.match(r'VARIABLES = (.*$)', line, re.M | re.I)
        C = re.match(r'ZONE (.*$)', line, re.M | re.I)
        if A or B or C:
                continue
        else:
            D = re.match(r'(.*$)', line, re.M | re.I)
            value = "{:.16}".format(D.group(1))
            y.append(float(value))
            j = j+1
            if j == 18:
                j = 0

感谢您的帮助!

【问题讨论】:

  • 在你的例子中,每一行正好有 6 列。情况是否总是如此,或者您是否必须处理最后一行的字段少于前一行的情况?例如,如果I=17,文件是什么样的?
  • 不,它并不总是 6 列。如果I = 17,则表示x将包含在第17个数字中。

标签: python numpy io converter


【解决方案1】:

用最后一个选项解决了:

arrays = []
with open(file, 'r') as a:
    for line in a.readlines():
        A = re.match(r'TITLE = (.*$)', line, re.M | re.I)
        B = re.match(r'VARIABLES = (.*$)', line, re.M | re.I)
        C = re.match(r'ZONE (.*$)', line, re.M | re.I)
        if A or B or C:
                continue
        else:
            arrays.append([float(s) for s in line.split()])
arrays = np.concatenate(arrays)

len_var = len(arrays)
x = arrays[0:len_var/2-1]
y = arrays[len_var/2:len_var]

这个答案对数组的创建有很大帮助:https://stackoverflow.com/a/4289557/6522112,这个答案也对遍历数组有很大帮助:https://stackoverflow.com/a/952952/6522112。但最后使用np.concatenate 似乎更好。

为了记录,我创建了这个函数来读取任何文件:

def tecplot_reader(file, nb_var):
    """Tecplot reader."""
    arrays = []
    with open(file, 'r') as a:
        for idx, line in enumerate(a.readlines()):
            if idx < 3:
                continue
            else:
                arrays.append([float(s) for s in line.split()])

    arrays = np.concatenate(arrays)
    output = np.split(arrays, nb_var)

    return output

那就这样吧:x, y, z = tecplot_reader('./file', 3)

【讨论】:

    【解决方案2】:

    这可能对其他人有用,所以我会在这里发布。我修改了@Y0da 的代码,以便他的函数可以一次性输出多个检测器的结果。也就是说你有一个 tecplot 文件的形式

     Title="test"
     Variables = "var1", "var2", "var3" ,
     "var4","var5"
     Zone T ="Detector =           1 "
      0.000000000000000E+000  0.000000000000000E+000  0.000000000000000E+000
      0.000000000000000E+000  0.000000000000000E+000
       50.0000000000000       0.000000000000000E+000  0.000000000000000E+000
      0.000000000000000E+000  0.000000000000000E+000
    
     Zone T ="Detector =           2 "
      0.000000000000000E+000  0.000000000000000E+000  0.000000000000000E+000
      0.000000000000000E+000  0.000000000000000E+000
       50.0000000000000       0.000000000000000E+000  0.000000000000000E+000
      0.000000000000000E+000  0.000000000000000E+000
    

    请注意,格式是故意丑陋的。这是因为如果您的输出来自 FORTRAN 代码,并且您在没有明确格式化的情况下写入文件,则使用的列数是有限的。

    import re
    import numpy as np
    import matplotlib.pyplot as plt
    
    path = 'path_to_file/file.plt'
    
    def tecplot_reader(file, nb_var):
        """Tecplot reader for multiple detectors"""
        detectors = []
        with open(file, 'r') as a:
            lines = a.readlines()
            for idx, line in enumerate(lines):
                if (idx <= 3) : continue                        # If this is header line skip
                detec = re.match(r' ZONE (.*$)', line, re.M | re.I) # Determine if this is a new detector line
                if (type(detec)!=type(None)):                       # If this is a new detector line
                    detector = int(line[20:-3])-1               # The detector index is between column 30 and -3 characters (counting starts at 1 for the output file)
                    detectors.append([])                        # Add a new list for this detector
                    continue
                else:
                    detectors[detector].append([float(s) for s in line.split()])
    
        for i,detec in enumerate(detectors):    # For each detector
            detectors[i] = np.concatenate(np.array(detec))                            # Concatinate into one array
            detectors[i] = np.split(np.array(detectors[i]),len(detectors[i])/nb_var)  # Break into correct rows (each row has nb_vars)
            detectors[i] = np.hsplit(np.array(detectors[i]),nb_var)                   # Break up vertically
        return detectors
    

    返回的是每个检测器的变量列表。

    【讨论】:

    • 这对我来说非常有用,但是在使用它时我收到了local variable 'detector' referenced before assignment 错误。 nb_var 应该是我想读的变量数吧?
    猜你喜欢
    • 2013-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-05
    • 2012-09-19
    • 1970-01-01
    • 2016-03-10
    • 2011-04-10
    相关资源
    最近更新 更多