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
У меня есть координаты полигонов в этом формате, показанном выше. Каждый многоугольник начинается с «границы» и заканчивается «эндель». У меня возникли проблемы с извлечением номера слоя, количества точек и координат в массив 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 ответа
Вы можете использовать простой код, например:
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 или что угодно, но обратите внимание, что в приведенном выше коде координаты по-прежнему являются строками.
Вы можете использовать регулярное выражение для разбора этого файла на блоки соответствующих данных, а затем для анализа каждого блока:
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
, чтобы файл казался находящимся в памяти.
Похожие вопросы
Связанные вопросы
Новые вопросы
python
Python - это многопарадигмальный, динамически типизированный, многоцелевой язык программирования. Он разработан для быстрого изучения, понимания и использования, а также для обеспечения чистого и единообразного синтаксиса. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Тем не менее, для вопросов о Python, связанных с версией, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas и NumPy) включите его в теги.