Python 如何在isalpha()和换行符之间将xy数据块拆分为列表\n

Python 如何在isalpha()和换行符之间将xy数据块拆分为列表\n,python,list,loops,if-statement,Python,List,Loops,If Statement,我得到了一个数字字符串的清理数据文件,表示多边形的坐标。我有过将数据文件中的一个多边形数据指定到列中并在numpy/matplotlib中打印它的经验,但为此,我必须从一个数据文件中打印多个多边形,并用标题分隔。数据的大小也不均匀;每个标题在两列中有几行数据,但行数不同 i、 e.我使用了.readlines()来: # Title of the polygons # a comment on the datasource # A comment on polygon projection Po

我得到了一个数字字符串的清理数据文件,表示多边形的坐标。我有过将数据文件中的一个多边形数据指定到列中并在numpy/matplotlib中打印它的经验,但为此,我必须从一个数据文件中打印多个多边形,并用标题分隔。数据的大小也不均匀;每个标题在两列中有几行数据,但行数不同

i、 e.我使用了
.readlines()
来:

# Title of the polygons
# a comment on the datasource
# A comment on polygon projection
Poly Two/a bit
(331222.6210000003, 672917.1531000007)
(331336.0946000004, 672911.7816000003)
(331488.4949000003, 672932.4191999994)
##etc

Poly One
[(331393.15660000034, 671982.1392999999), (331477.28839999996, 671959.8816), (331602.10170000046, 671926.8432999998), (331767.28160000034, 671894.7273999993), (331767.28529999964, 671894.7267000005), (##etc)]
致:

到目前为止,我的代码包括清理原始数据集,使其与上面所示的一样

data_easting=[]
data_northing=[]

County = open('counties.dat','r')

for line in County.readlines():

    if line.lstrip().startswith('#'):
        print ('Comment line ignored and leading whitespace removed')
        continue

    line = line.replace('/','and').replace(' ','').replace('[','').replace(']','').replace('),(','\n')
    line = line.strip('()\n')
    print (line)

    if line.isalpha():
        print ('Skipped header: '+ line)
        continue
到目前为止,我一直在使用
isalpha():
忽略每个多边形的标题,我计划使用
if line='\n':continue
line.split(',')
忽略数据之间的换行,并开始拆分东距和北距列表。我已经对代码的numpy和matplotlib部分(未显示)进行了排序,以生成一个多边形,但我不知道如何实现它来绘制多个阵列/多个多边形

但我很早就意识到,如果我试图将所有数据分配给2X和y列表,那只会产生一个巨大的无休止的多边形,它会把我的绘图弄得一团糟,因为会画出假想线将它们连接起来

我想使用
isalpha()
部分来识别和制作多边形名称的字典或列表,并为每个多边形数据块附加一个数组,但我不确定如何实现它(或者如果可以)。我也不确定如何使它停止将数据加载到多边形数据块末尾的列表中(可能是
如果line='\n':break
?但是如何使它在每个数据块上再启动和停止149次?)

更为困难的是,该文件中有150个多边形包含x和y数据,因此为每个多边形创建150个x和y列表并为每个多边形编写特定代码不是很有效

那么,我基本上如何做到:

if line.isalpha():
    #(assign to a Counties dictionary or a list as PolyOne, PolyTwo,...PolyOneHundredFifty)
    #(a way of getting the data between the header and newline into a separate list)
    #(a way to relate that PolyOne Data list of x and y to the dictionary "PolyOne")

if line == '\n':
    #(break? continue?)
    #(then restart and repeat for PolyTwo,...PolyOneHundredFifty)

line.split (',')
data_easting.append(x) #x1,x2,...x150?
data_northing.append(y) #y1,y2,y150?)
有没有办法做到我想做的事?没有熊猫我怎么办


感谢您抽出时间。

解析原始数据/文件:

当您遇到一条线/块,如示例中的第二条线/块

>>> s = '''[(331393.15660000034, 671982.1392999999), (331477.28839999996, 671959.8816), (331602.10170000046, 671926.8432999998), (331767.28160000034, 671894.7273999993), (331767.28529999964, 671894.7267000005)]'''
它可以直接转换为2d numpy数组,如下所示,使用它可以安全地将文本转换为python对象,在本例中是元组列表

>>> import numpy as np
>>> import ast
>>> if s.startswith('['):
    #print(ast.literal_eval(s))
    array = np.array(ast.literal_eval(s))
    
>>> array
array([[331393.1566, 671982.1393],
       [331477.2884, 671959.8816],
       [331602.1017, 671926.8433],
       [331767.2816, 671894.7274],
       [331767.2853, 671894.7267]])
>>> array.shape
(5, 2)

对于与(原始)示例中的第一个块相似的块,当到达下一个块时,将每一行累积为列表中的浮点元组,并将其重置为该列表的数组。我把这些都放在一个生成函数中,生成块作为二维数组

import ast
import numpy as np

def parse(lines_read):
    data = []
    for line in lines_read:
        if line.startswith('#'):
            continue
        elif line.startswith('('):
            n,e = line[1:-2].split(',')
            data.append((float(n),float(e)))
        elif line.startswith('['):
            array = np.array(ast.literal_eval(line))
            yield array
        else:
            if data:
                array = np.array(data)
                data = []
                yield array
像这样使用

>>> for block in parse(f.readlines()):
...    print(block)
...    print('*******************')

[[331222.621  672917.1531]
 [331336.0946 672911.7816]
 [331488.4949 672932.4192]]
*******************
[[331393.1566 671982.1393]
 [331477.2884 671959.8816]
 [331602.1017 671926.8433]
 [331767.2816 671894.7274]
 [331767.2853 671894.7267]]
*******************
>>>

如果需要单独选择“北距”或“东距”列,请参阅


使用两个正则表达式进行解析。这对作为字符串读取的整个文件进行操作:
s=fileobject.read()
。它需要检查文件两次,并且不保留块顺序

import re, ast
import numpy as np

pattern1 = re.compile(r'(\n\([^)]+\))+')
pattern2 = re.compile(r'^\[[^]]+\]',flags=re.MULTILINE)

for m in pattern1.finditer(s):
    block = m.group().strip().split('\n')
    data = []
    for line in block:
        line = line[1:-1]
        n,e = map(float,line.split(','))
        data.append((n,e))
    print(np.array(data))
    print('****')

for m in pattern2.finditer(s):
    print(np.array(ast.literal_eval(m.group())))
    print('****')

您希望这些最终采用什么格式/数据结构?此外,分隔符是否总是在多边形之间有两条换行符?在清理之前,您可能还希望包含一个原始数据的示例。也许不需要中间步骤就可以将原始数据读入所需的格式。我希望每个数据块位于两个numpy浮点数组中,x(东距)和y(北距)。分隔符是常量,总是两个换行符(\n\n)。标题对于最终的绘图来说并不是至关重要的,但我刚刚找到了如何将它们放入字典中的方法,所以希望我能在最后一步将每个数据块放入数组,并以某种方式将它们分配给每个字典值。我希望这是有道理的@第二次世界大战,我现在会给你一份副本,并为你更新问题,但我认为原始数据文件的要点是要清理,因为它到处都是。也许也可以将它添加到问题的底部,用一个分隔它的符号。以及它来自何处以及是否有文档解释它的格式。这将有助于处理那些[]封闭块,但如果每个块依赖于定义
数组=
,那么它不会被下一个[]封闭块覆盖吗?我很感激你的回答,但我仍然有一个主要的问题,那就是把所有的块附加起来,作为独立的多边形一起绘制。
import re, ast
import numpy as np

pattern1 = re.compile(r'(\n\([^)]+\))+')
pattern2 = re.compile(r'^\[[^]]+\]',flags=re.MULTILINE)

for m in pattern1.finditer(s):
    block = m.group().strip().split('\n')
    data = []
    for line in block:
        line = line[1:-1]
        n,e = map(float,line.split(','))
        data.append((n,e))
    print(np.array(data))
    print('****')

for m in pattern2.finditer(s):
    print(np.array(ast.literal_eval(m.group())))
    print('****')