#python #algorithm #numpy
#python #алгоритм #numpy
Вопрос:
Я хочу автоматически создать несколько пар на основе данных, хранящихся в виде массивов numpy. Фактически, числа в моих первых массивах — это номера нескольких строк. Я хочу соединить линии и создать поверхности, используя созданные пары. Это массив строк:
line_no= np.arange (17, 25)
Эти строки расположены в двух перпендикулярных направлениях. Я загрузил рисунок, чтобы показать его (они имеют синий и красный цвета). Я знаю, где меняется направление моих строк, и вызываю его как sep
.
sep=20
Другие данные, которые должны быть полезными, — это количество точек, создающих строки. Я называю это rep
.
rep = np.array([3,3,1])
Затем я использовал следующий код для достижения своей цели, но это неверно:
start =line_no[0]
N_x = len(rep) - 1
N_y = max(rep) - 1
grid = np.zeros((N_y 1, N_x 1, 2))
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 = 0
for i in range(N_x):
for j in range(N_y, -1, -1):
if j >= kxs[i 1]:
continue
grid[j,i,0] = lines[lines_before]
lines_before = 1
for i in range(N_x 1):
for j in range(N_y-1, -1, -1):
if j < rep[i] - 1:
grid[j,i,1] = lines[lines_before]
lines_before = 1
joints=np.array([])
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):
new_joints = square
joints=np.append (new_joints,joints)
На моем рисунке у меня есть два сценария: A ( rep = np.array([3,3,1])
) и B ( rep = np.array([1,3,3])
). Для A я хочу иметь следующие пары:
17, 21, 18, 23
18, 22, 19, 24
И для B:
18, 21, 19, 23
19, 22, 20, 24
На самом деле распределение моих строк может измениться. Например, в сценарии A последняя строка не создает никакой поверхности, а в B первая не находится ни на одной поверхности, и в случае, если у меня может быть несколько строк, которые не являются частью какой-либо поверхности. Например, у меня может быть другая красная строка с номером строки ниже 21
, которая не создает никакой поверхности. Спасибо, что обратили внимание на мою проблему. Я заранее признателен за любую помощь.
Более сложный случай также показан ниже. В сценарии C у меня есть:
line_no= np.arange (17, 42)
sep=29
rep = np.array([5,4,4,2,2,1])
В сценарии D у меня есть:
line_no= np.arange (17, 33)
sep=24
rep = np.array([1,3,4,4])
Ответ №1:
Извините, но я не смог пройти через вашу реализацию. Совет на следующий раз — пожалуйста, попробуйте прокомментировать свой код, это помогает.
В любом случае, вот несколько удобочитаемая реализация, которая выполняет эту работу. Но я советую вам проверить больше сценариев, чтобы проверить правильность сценариев, прежде чем делать какие-либо выводы.
import numpy as np
line_no = np.arange(17, 25)
sep = 20 # this information is redundant for the problem
nodes = np.array(np.array([1,3,4,4]))
# for generalised implementation hlines start from 0 and vlines start where hlines end
# offset parameter can be used to change the origin or start number of hlines and hence changed the vlines also
offset = 17
# calculate the number of horizontal lines and vertical lines in sequence
hlines = np.array([min(a, b) for a, b in zip(nodes[:-1], nodes[1:])])
# vlines = np.array([max(a, b) - 1 for a, b in zip(nodes[:-1], nodes[1:])])
vlines = nodes - 1
print(f"hlines: {hlines}, vlines: {vlines}")
# nodes = np.array([3, 3, 1]) ---> hlines: [3, 1], vlines: [2, 2]
# nodes = np.array([1, 3, 3]) ---> hlines: [1, 3], vlines: [2, 2]
hlines_no = list(range(sum(hlines)))
vlines_no = list(range(sum(hlines), sum(hlines) sum(vlines)))
print(f"hlines numbers: {hlines_no}, vlines numbers: {vlines_no}")
# nodes = np.array([3, 3, 1]) ---> hlines numbers: [0, 1, 2, 3], vlines numbers: [4, 5, 6, 7]
# nodes = np.array([1, 3, 3]) ---> hlines numbers: [0, 1, 2, 3], vlines numbers: [4, 5, 6, 7]
cells = [] # to store complete cell tuples
hidx = 0 # to keep track of horizontal lines index
vidx = 0 # to keep track of vertical lines index
previous_cells = 0
current_cells = 0
for LN, RN in zip(nodes[:-1], nodes[1:]):
# if either the left or right side nodes is equal to 1, implies only 1 horizontal line exists
# and the horizontal index is updated
if LN == 1 or RN == 1:
hidx = 1
else:
# to handle just a blank vertical line
if LN - RN == 1:
vidx = 1
# iterate 'cell' number of times
# number of cells are always 1 less than the minimum of left and right side nodes
current_cells = min(LN, RN)-1
if previous_cells != 0 and previous_cells > current_cells:
vidx = previous_cells - current_cells
for C in range(current_cells):
cell = (offset hlines_no[hidx],
offset vlines_no[vidx],
offset hlines_no[hidx 1],
offset vlines_no[vidx current_cells])
hidx = 1
vidx = 1
cells.append(cell)
# skip the last horizontal line in a column
hidx = 1
previous_cells = min(LN, RN)-1
print(cells)
Результаты
# nodes = np.array([3, 3, 1]) ---> [(17, 21, 18, 23), (18, 22, 19, 24)]
# nodes = np.array([1, 3, 3]) ---> [(18, 21, 19, 23), (19, 22, 20, 24)]
# nodes = np.array([5,4,4,2,2,1]) ---> [(17, 31, 18, 34),
# (18, 32, 19, 35),
# (19, 33, 20, 36),
# (21, 34, 22, 37),
# (22, 35, 23, 38),
# (23, 36, 24, 39),
# (25, 39, 26, 40),
# (27, 40, 28, 41)]
# nodes = np.array([1,3,4,4]) ---> [(18, 25, 19, 27),
# (19, 26, 20, 28),
# (21, 27, 22, 30),
# (22, 28, 23, 31),
# (23, 29, 24, 32)]
Редактировать: обновлен код для учета особых сценариев
Комментарии:
1. Уважаемый @sai, я ценю ваше решение. Извините за мой поздний отзыв. В то время меня не было перед моим рабочим столом, и я не мог это проверить. У меня всего две проблемы. Когда я добавляю еще одну строку в сценарий, приведенный ниже
21
, иnodes = np.array([4, 3, 1])
, у меня нет правильного результата. А также в реальности поверхности не создаются в столбце, они создают сетку. Например, в сценарии A вы можете думать, что в правой части существующих двух поверхностей также есть две другие:line_no=np.arange(17, 31)
,sep=23
иnodes = np.array([4, 4, 2, 1])
. Спасибо за такую поддержку.2. Можете ли вы добавить (картинки) другие сценарии крайнего случая, которые должен удовлетворять сценарий? Дополнительная информация помогла бы мне и всем остальным в SO получить полную картину и предоставить полное решение.
3. Дорогой @sai, я обновил свой пост, чтобы показать, чего я хочу. Заранее я ценю любой вклад.
4. Уважаемый @sai. Я действительно ценю вашу помощь. Проблема в том, что в других случаях я сталкиваюсь с ошибками. Например, допустим, в сценарии
D
я удаляю первую горизонтальную строку (число17
). Тогда у меня будетline_no = np.arange(18, 25)
,sep = 24
nodes = np.array(np.array([3,4,4]))
и все же у меня должны быть одинаковые поверхности, но я сталкиваюсь с ошибкой :IndexError: list index out of range
5. Попробуйте с
vlines = nodes - 1