Python 如何在isalpha()和换行符之间将xy数据块拆分为列表\n
我得到了一个数字字符串的清理数据文件,表示多边形的坐标。我有过将数据文件中的一个多边形数据指定到列中并在numpy/matplotlib中打印它的经验,但为此,我必须从一个数据文件中打印多个多边形,并用标题分隔。数据的大小也不均匀;每个标题在两列中有几行数据,但行数不同 i、 e.我使用了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
.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('****')