如何在python中使用适当的标签从文本文件中提取数字

时间:2018-01-06 15:12:02

标签: python pandas numpy

boundary
        layer 2
        datatype 0
        xy  15   525270 8663518   525400 8663518   525400 8664818   525660 8664818
                 525660 8663518   525790 8663518   525790 8664818   526050 8664818
                 526050 8663518   526180 8663518   526180 8665398   525980 8665598
                 525470 8665598   525270 8665398   525270 8663518
        endel

我有上面显示的这种格式的多边形坐标。每个多边形以"边界"开头。并以" endel"结束。我无法将层数,点数和坐标提取到numpy数组或pandas数据帧中。

具体到这个例子,我需要层数(2),点数(15)和x-y坐标对。

with open('source1.txt', encoding="utf-8") as f:
    for line in f:
        line = f.readline()
        srs= line.split("\t")
        print(srs)

这样做不会分割数字,即使它们被标签分隔

['        layer 255\n']
['        xy   5   0 0   22800000 0   22800000 22800000   0 22800000\n']
['        endel\n']

这是我得到的结果

with open('source1.txt', encoding="utf-8") as f:
    for line in f:
        line = f.readline()
        srs= line.split(" ")
        print(srs)

这不是我想要的,但我也试过了,但却得到了一个糟糕的分裂

['', '', '', '', '', '', '', '', 'layer', '255\n']
['', '', '', '', '', '', '', '', 'xy', '', '', '5', '', '', '0', '0', '', '', '22800000', '0', '', '', '22800000', '22800000', '', '', '0', '22800000\n']
['', '', '', '', '', '', '', '', 'endel\n']

我无法进入numpy部分因为我处理文件中的字符串

根据要求编辑

2 个答案:

答案 0 :(得分:1)

您可以使用一些简单的代码,例如:

res = []
coords = []
xy = False
with open('data.txt') as f:
    for line in f.readlines():
        if 'layer' in line:
            arr = line.split()
            layer = int(arr[-1].strip())
        elif 'xy' in line:
            arr = line.split()
            npoints = int(arr[1])
            coords = arr[2:]
            xy = True
        elif 'endel' in line:
            res.append([layer, npoints, coords[0:npoints]])
            xy = False
            coords = []
        elif xy:
            coords.extend(line.split())
print(res)

然后,您可以将结果列表转换为numpy数组,或者您喜欢的任何内容,但请注意,coords仍然是上面代码中的字符串。

答案 1 :(得分:0)

您可以使用正则表达式将该文件解析为相关数据的块,然后解析每个块:

for block in re.findall(r'^boundary([\s\S]+?)endel', f.read()):
    m1=re.search(r'^\s*layer\s+(\d+)', block, re.M)
    m2=re.search(r'^\s*datatype\s+(\d+)', block, re.M)
    m3=re.search(r'^\s*xy\s+(\d+)\s+([\s\d]+)', block, re.M)
    if m1 and m2 and m3:
        layer=int(m1.group(1))
        datatype=int(m2.group(1))
        xy=int(m3.group(1))
        coordinates=[(int(x),int(y)) for x,y in zip(*[iter(m3.group(2).split())]*2)]
    else:
        print "can't parse {}".format(block)  

xy之后支持可变数量的坐标,并且测试解析的坐标数是len(coordinates)==xy预期的数量是微不足道的。

如上所述,这需要将整个文件读入内存。如果大小是一个问题(并且通常不适用于中小型文件),您可以使用mmap使文件出现在内存中。