Python 如何将文件读取为多个多边形的嵌套坐标列表?
我有一个包含以下许多部分的文件:Python 如何将文件读取为多个多边形的嵌套坐标列表?,python,regex,python-3.x,file-io,matplotlib,Python,Regex,Python 3.x,File Io,Matplotlib,我有一个包含以下许多部分的文件: [40.742742,-73.993847] [40.739389,-73.985667] [40.74715499999999,-73.97992] [40.750573,-73.988415] [40.742742,-73.993847] [40.734706,-73.991915] [40.736917,-73.990263] [40.736104,-73.98846] [40.740315,-73.985263] [40.74364800000001,
[40.742742,-73.993847]
[40.739389,-73.985667]
[40.74715499999999,-73.97992]
[40.750573,-73.988415]
[40.742742,-73.993847]
[40.734706,-73.991915]
[40.736917,-73.990263]
[40.736104,-73.98846]
[40.740315,-73.985263]
[40.74364800000001,-73.993353]
[40.73729099999999,-73.997988]
[40.734706,-73.991915]
[40.729226,-74.003463]
[40.7214529,-74.006038]
[40.717745,-74.000389]
[40.722299,-73.996634]
[40.725291,-73.994413]
[40.729226,-74.003463]
[40.754604,-74.007836]
[40.751289,-74.000649]
[40.7547179,-73.9983309]
[40.75779,-74.0054339]
[40.754604,-74.007836]
我需要在这些部分中阅读成对坐标的列表(每个部分由一个额外的\n
分隔)
在一个类似的文件中(除了没有额外的换行符外,其他文件相同),我从整个文件中绘制一个多边形。我可以使用以下代码读取坐标并在matplotlib中绘制它:
mVerts = []
with open('Manhattan_Coords.txt') as f:
for line in f:
pair = [float(s) for s in line.strip()[1:-1].split(", ")]
mVerts.append(pair)
plt.plot(*zip(*mVerts))
plt.show()
我如何才能完成同样的任务,除了使用多个多边形,文件中的每个多边形都用一个额外的换行符分隔?以下是我个人最喜欢的将文件“分块”为多组以空格分隔的对象的方法:
from itertools import groupby
def chunk_groups(it):
stripped_lines = (x.strip() for x in it)
for k, group in groupby(stripped_lines, bool):
if k:
yield list(group)
我建议ast.literal\u eval
将列表的字符串表示形式转换为实际的python列表:
from ast import literal_eval
with open(filename) as f:
result = [[literal_eval(li) for li in chunk] for chunk in chunk_groups(f)]
给出:
result
Out[66]:
[[[40.742742, -73.993847],
[40.739389, -73.985667],
[40.74715499999999, -73.97992],
[40.750573, -73.988415],
[40.742742, -73.993847]],
[[40.734706, -73.991915],
[40.736917, -73.990263],
[40.736104, -73.98846],
[40.740315, -73.985263],
[40.74364800000001, -73.993353],
[40.73729099999999, -73.997988],
[40.734706, -73.991915]],
[[40.729226, -74.003463],
[40.7214529, -74.006038],
[40.717745, -74.000389],
[40.722299, -73.996634],
[40.725291, -73.994413],
[40.729226, -74.003463],
[40.754604, -74.007836],
[40.751289, -74.000649],
[40.7547179, -73.9983309],
[40.75779, -74.0054339],
[40.754604, -74.007836]]]
以下是我个人最喜欢的将文件“分块”到由空格分隔的组中的方法:
from itertools import groupby
def chunk_groups(it):
stripped_lines = (x.strip() for x in it)
for k, group in groupby(stripped_lines, bool):
if k:
yield list(group)
我建议ast.literal\u eval
将列表的字符串表示形式转换为实际的python列表:
from ast import literal_eval
with open(filename) as f:
result = [[literal_eval(li) for li in chunk] for chunk in chunk_groups(f)]
给出:
result
Out[66]:
[[[40.742742, -73.993847],
[40.739389, -73.985667],
[40.74715499999999, -73.97992],
[40.750573, -73.988415],
[40.742742, -73.993847]],
[[40.734706, -73.991915],
[40.736917, -73.990263],
[40.736104, -73.98846],
[40.740315, -73.985263],
[40.74364800000001, -73.993353],
[40.73729099999999, -73.997988],
[40.734706, -73.991915]],
[[40.729226, -74.003463],
[40.7214529, -74.006038],
[40.717745, -74.000389],
[40.722299, -73.996634],
[40.725291, -73.994413],
[40.729226, -74.003463],
[40.754604, -74.007836],
[40.751289, -74.000649],
[40.7547179, -73.9983309],
[40.75779, -74.0054339],
[40.754604, -74.007836]]]
roippi的想法略有不同,使用了
json
而不是ast
import json
from itertools import groupby
with open(FILE, "r") as coodinates_file:
grouped = groupby(coodinates_file, lambda line: line.isspace())
groups = (group for empty, group in grouped if not empty)
polygons = [[json.loads(line) for line in group] for group in groups]
roippi的想法略有不同,使用了
json
而不是ast
import json
from itertools import groupby
with open(FILE, "r") as coodinates_file:
grouped = groupby(coodinates_file, lambda line: line.isspace())
groups = (group for empty, group in grouped if not empty)
polygons = [[json.loads(line) for line in group] for group in groups]
在已经发布的答案中有很多巧妙的方法。他们都没问题 然而,采取显而易见但可读的方法也没有什么错 另一方面,您似乎正在处理地理数据。这种格式在任何时候都会遇到,而段分隔符通常不像额外的换行符那样明显。(有很多非常糟糕的特殊“ascii导出”格式,尤其是在晦涩难懂的专有软件中。例如,一种常见格式使用段中最后一行末尾的
F
作为分隔符(即1.0 2.0F
)。许多其他文件根本不使用分隔符,如果距离最后一个点超过“x”距离,则需要启动新的线段/多边形。)此外,这些文件通常是多GB ascii文件,因此将整个文件读入内存可能是不切实际的
我的观点是:无论你选择哪种方法,都要确保你理解它。你会再次这样做,它会变得非常不同,很难概括。您绝对应该好好学习像
itertools
这样的库,但要确保您完全理解所调用的函数
以下是“显而易见但可读”方法的一个版本。它更加冗长,但没有人会对它的作用感到困惑。(你可以用几种稍有不同的方式编写相同的逻辑。使用对你最有意义的方式。)
在已经发布的答案中,有很多巧妙的方法。他们都没问题 然而,采取显而易见但可读的方法也没有什么错 另一方面,您似乎正在处理地理数据。这种格式在任何时候都会遇到,而段分隔符通常不像额外的换行符那样明显。(有很多非常糟糕的特殊“ascii导出”格式,尤其是在晦涩难懂的专有软件中。例如,一种常见格式使用段中最后一行末尾的
F
作为分隔符(即1.0 2.0F
)。许多其他文件根本不使用分隔符,如果距离最后一个点超过“x”距离,则需要启动新的线段/多边形。)此外,这些文件通常是多GB ascii文件,因此将整个文件读入内存可能是不切实际的
我的观点是:无论你选择哪种方法,都要确保你理解它。你会再次这样做,它会变得非常不同,很难概括。您绝对应该好好学习像
itertools
这样的库,但要确保您完全理解所调用的函数
以下是“显而易见但可读”方法的一个版本。它更加冗长,但没有人会对它的作用感到困惑。(你可以用几种稍有不同的方式编写相同的逻辑。使用对你最有意义的方式。)
为什么新线是相关的?表格是
[#,#]
。你的意思是说可能存在将这三个坐标与其他坐标分开的[#]、[#]、[#]、[#]、[#]、#]\n
\n[#,#]\n\n是一个多边形,在该换行符之前有任意给定数量的坐标。您可以将每一行解析为字符串,然后使用正则表达式查找每一对。是你遇到麻烦的正则表达式吗,比如去掉装饰[,]
?我可以使用正则表达式找到每一对,并将所有这些对放入一个列表中,但我需要一种用这些对创建子列表的方法,当找到额外的换行符时,每个坐标子列表都会被截断,开始下一个坐标子列表。这个输入来自哪里?它看起来非常像是有人将每个Python列表的repr
写入一个文件,或者将其存储为JSON。如果这是真的,为什么不直接用ast.literal\u eval
或json.load
适当地解析它呢?为什么换行符是相关的?表格是[#,#]
。你的意思是说可能存在将这三个坐标与其他坐标分开的[#]、[#]、[#]、[#]、[#]、#]\n
\n[#,#]\n\n是一个多边形,在该换行符之前有任意给定数量的坐标。您可以将每一行解析为字符串,然后使用正则表达式查找每一对。是你遇到麻烦的正则表达式吗,比如去掉装饰[,]
?我可以使用正则表达式找到每一对,并将所有这些对放入一个列表中,