首页 > 解决方案 > 如何在 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]))。对于 AI 想要有以下对:

17, 21, 18, 23
18, 22, 19, 24

对于 B:

18, 21, 19, 23
19, 22, 20, 24

实际上,我的线路分布可以改变。例如,在场景 A 中,最后一条线没有创建任何表面,而在 B 中,第一条线不在任何表面中,如果我可能有几条线不属于任何表面。例如,我可能在行号下面有另一条红线21,它不构成任何表面。感谢您关注我的问题。我非常感谢您提前提供的任何帮助。

在此处输入图像描述

下面还展示了一个更复杂的情况。在场景中 CI 有:

line_no= np.arange (17, 42)
sep=29
rep = np.array([5,4,4,2,2,1])

在场景 DI 中有:

line_no= np.arange (17, 33)
sep=24
rep = np.array([1,3,4,4])

在此处输入图像描述

标签: pythonalgorithmnumpy

解决方案


抱歉,我无法完成您的实施。下次提示 - 请尝试评论您的代码,它会有所帮助。

无论如何,这里有一些可以完成工作的可读实现。但是,我建议您在做出任何结论之前检查更多场景以验证脚本的有效性。

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)]

编辑:更新了代码以考虑特殊情况


推荐阅读