Как разработать алгоритм сопряжения данных массива numpy

У меня есть несколько точек в 3D, и после их соединения я создал с их помощью несколько линий. Теперь у меня есть номера строк в виде массива NumPy, но я не знаю, как соединить количество строк.

lines=np.arange (17, 31)

На самом деле номера строк поверхностей какие-то беспорядочные. Линии в двух наборах, и каждый набор параллельный (синяя и красная линии на загруженном рисунке). Я также знаю две другие вещи: последнее число изменения направления линии (sep), а также количество точек второго набора линий (красные) (rep).

sep=23
rep=np.array ([4,3,3,1])

На основе моего рисунка у меня есть четыре поверхности, созданные линиями с номерами 17-25-18-27, 18-26-19-28, 20-27-21-29 и 21-28-22-30. Я создал следующий код для создания таких пар, но он вообще не удался:

for i in lines:
        if rep[0]==rep[1]:
            print (i, sep+1, i+1, sep+1)
        elif rep[0]!=rep[1]:
            print (i, sep+1+np.abs (rep[1]-rep[0]), i+1, sep+1+np.abs (rep[1]-rep[0])+ 1 + np.abs (rep[1]-rep[0]))

На самом деле, я хочу, чтобы алгоритм печатал следующее:

17, 25, 18, 27
18, 26, 19, 28
20, 27, 21, 29
21, 28, 22, 30

Я признателен, если кто-нибудь поможет мне создать такой алгоритм, который может генерировать пары поверхностей. На самом деле мой массив lines больше. Я хочу найти способ создания поверхностей на основе rep, sep и lines. Заранее, я ценю любую помощь. Спасибо, что уделили время.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
95
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Не очень навороченный способ — построить сетку линий, а затем собрать из сетки 4 кортежа линий.

Во-первых, преамбула:

#! /usr/bin/env python3

import numpy as np

start = 17
sep = 23
rep = np.array([4,3,3,1])

Чтобы построить сетку, обратите внимание, что здесь длина rep — это длина сетки по оси x, а максимальное значение rep — это длина по оси y. Однако мы строим сетку из линий, а не из точек, поэтому в каждом направлении на 1 меньше. Обратите внимание, что я использую N_y и N_x именно в таком порядке, чтобы простая печать отображала сетку в формате, более близком к диаграмме на картинке.

N_x = len(rep) - 1
N_y = max(rep) - 1
grid = np.zeros((N_y, N_x, 2))

Сколько горизонтальных линий в каждом столбце? Для столбца, образованного точками (x_i, y) и (x_i+1, y), это min(rep[i], rep[i+1]) - количество точек в меньшем столбце. Для столбца 0 это 0 — слева от сетки ничего нет. Это также дает нам общее количество горизонтальных линий.

Количество вертикальных линий в каждом столбце легко определить — это количество точек по оси Y — 1. (И, следовательно, общее количество вертикальных линий равно сумме rep — длины rep.)

kxs = [0] + [min(rep[i], rep[i+1]) for i in range(len(rep)-1)]
T_x = sum(kxs)
T_y = sum(rep) - len(rep)
T_total = T_x + T_y

lines = np.arange(start, start+T_total)

Приступаем к заполнению сетки. Индексация здесь неудобна, поскольку мы заполняем ее снизу вверх, а оси меняются местами, как упоминалось ранее. Идем слева направо и снизу вверх.

# `lines_before` is essentially, an index into the `lines` array,
# keeping track of how many lines have already been used
lines_before = 0
for i in range(N_x):
    for j in range(N_y-1, -1, -1):
        if j >= kxs[i+1]:
            # We haven't reached the minimum depth (or height, however you think of it)
            continue
        grid[j,i,0] = lines[lines_before]
        lines_before += 1
print(grid[:,:,0])

for i in range(N_x):
    for j in range(N_y-1, -1, -1):
        if j < rep[i] - 1:
            grid[j,i,1] = lines[lines_before]
            lines_before += 1
print(grid[:,:,1])

На данный момент вывод для чисел в вопросе:

[[19. 22. 23.]
 [18. 21.  0.]
 [17. 20.  0.]]
[[26. 28. 30.]
 [25. 27. 29.]
 [24.  0.  0.]]

Номера строк совпадают с изображением, а нули теперь указывают, где линий нет.

Теперь мы можем собирать наборы линий. Начиная сверху, и двигаясь слева направо и сверху вниз, в каждой позиции собираем горизонтальную линию там и ту, что под ней, и вертикальную линию там и ту, что справа от нее. (Тогда из изображения будут взяты (19, 18, 26, 28), (18, 17, 25, 27) и т. д.) Для каждого собранного набора, если какое-либо число равно нулю, это означает, что в нем отсутствует линию, и мы можем устранить ее. Так:

for i in range(N_x - 1):
    for j in range(N_y - 1):
        square = np.append(grid[j:j+2, i, 0], grid[j, i:i+2, 1])
        if all(square):
            print(square)

Предоставление:

[19. 18. 26. 28.]
[18. 17. 25. 27.]
[22. 21. 28. 30.]
[21. 20. 27. 29.]

Это не в том порядке, в котором вы хотите, и мы строим сетку, что может быть слишком дорого, но я оставляю порядок и оптимизацию в качестве упражнения со следующими примечаниями:

  1. Из kxs и rep можно определить номер строки в каждой позиции сетки, поэтому сетка нам вообще не нужна.
  2. Порядок — это просто вопрос того, в каком направлении вы перемещаетесь по сетке.

В этом случае сетки больше в разных направлениях для x и y. Таким образом, grid само будет np.zeros((N_y + 1, N_x + 1, 2)), а в циклах цикл для x будет иметь for j in range(N_y, -1, -1), а цикл для y будет иметь for i in range(N_x+1), что дает результат [20. 19. 22. 24.] и [19. 18. 21. 23.].

muru 14.12.2020 13:10

Уважаемый @muru, спасибо за то, что очень помогли. Есть ли возможность смешать их обоих? Я имею в виду, скажем, sep=25 и rep = np.array([4,3,1,1,4,4]). Тогда у меня должно быть пять поверхностей.

Ali_d 14.12.2020 13:17

Разве вы не получаете 5 наборов строк, используя модификации в моем последнем комментарии?

muru 14.12.2020 13:27

К сожалению, нет, это дает мне две первые поверхности, которые неверны.

Ali_d 14.12.2020 13:34

Другие вопросы по теме