繁体   English   中英

在Python列表中查找所有矩形

[英]Finding all rectangles in Python list

我有一个python列表:

[
[1, 1, 2],
[1, 1, 2],
[7, 4, 5],
[5, 3, 7],
]

我需要在此2D数组中找到满足以下条件的所有矩形(有多少个矩形):
1.一个矩形中的所有数字必须相同
2.该矩形中的数字不能在数组中的任何其他位置
3.并不是真正的标准,而是一些额外的信息:
矩形尺寸可以是1x1、2x1、2x2、3x1、3x2、3x3、3x4等。

在此示例中,数字有5个矩形:

1, 2, 3, 4

而数字3、1、8不符合条件,因为:

5-违反规则2
7-违反规则2

我尝试过类似查找与它们进行比较的最接近元素,如果它们匹配则向下一行等等,但是我做不到,所以希望有人能提供帮助。 谢谢。

一种方法是针对每个唯一值,在该值的所有实例上拟合一个矩形。 如果该矩形内的所有值都匹配,则说明您已满足条件。 在这里,它是使用numpy在代码中实现的,打印出符合条件的值:

import numpy as np

arr = np.array([
    [3, 2, 2, 1, 4],
    [3, 2, 2, 7, 4],
    [8, 2, 2, 1, 3],
    [8, 8, 9, 9, 9],
    [8, 8, 1, 5, 1]
])
for n in np.unique(arr):
    y, x = np.where(arr == n)
    if (arr[y.min():y.max()+1, x.min():x.max()+1] == n).all():
        print(n)

更新

不那么漂亮,但是这样的事情不需要numpy:

lst = [
    [3, 2, 2, 1, 4],
    [3, 2, 2, 7, 4],
    [8, 2, 2, 1, 3],
    [8, 8, 9, 9, 9],
    [8, 8, 1, 5, 1]
]

for val in set([x for sub in lst for x in sub ]):
    y = [n for n, sub in enumerate(lst) if val in sub]
    if any(y):
        x = []
        for sub in [lst[n] for n in y]:
            x.extend([m for m, v in enumerate(sub) if v == val])

        rect = [i for sub in lst[min(y):max(y)+1] for i in sub[min(x):max(x)+1]]
        if all([i == val for i in rect]):
            print(val)

除了上面来自user3386109的注释,这是纯python代码,它将计算从左上角坐标到右下角坐标的矩形大小,并将其与总位数进行比较,看看它们是否相等。 如果是这样,则数字为矩形。

# create an empty result array
result = []

# check each digit one through nine
for num in range(1, 10):
    # create a list to store the coordinates of each found digit
    coords = []
    # rows loop
    for r in range(len(li)):
        # columns loop
        for c in range(len(li[0])):
            if li[r][c] == num:
                coords.append([r,c])
    # check for null coords list which means the digit is not in the matrix
    if len(coords) == 0:
        pass
    else:
        tl = coords[0]
        br = coords[-1]
        total = (br[0] - tl[0] + 1) * (br[1] - tl[1] + 1)
        if total == len(coords):
            result.append(num)
print('The digits that form rectangles are: ', result)

结果将如下所示:

The digits that form rectangles are:  [2, 4, 5, 7, 9]

另一种方法是考虑使用熊猫数据框。

import pandas as pd

从数字列表中制作一个数据框,如下所示:

df = pd.DataFrame([
[3, 2, 2, 1, 4],
[3, 2, 2, 7, 4],
[8, 2, 2, 1, 3],
[8, 8, 9, 9, 9],
[8, 8, 1, 5, 1]
])

然后,使用for循环测试每个1-9的数字(我假设列表中没有0?),然后在for循环中删除没有测试任何数字的行和列。 如果生成的框架确实是矩形,则应该没有'NaN'。

例如,数字1生成的帧如下所示:

      2   3   4
0    NaN 1.0 NaN
2    NaN 1.0 NaN
4    1.0 NaN 1.0

而数字2生成的帧如下所示:

     1   2
0   2.0 2.0
1   2.0 2.0
2   2.0 2.0

检查NaN是否为== 0,您将得到一个矩形。 您还需要确保该字段的大小不为零,因为这将指示不存在数字。 这是代码:

result = []
for num in range(1, 10):
    df_dna = df[df == num].dropna(how="all", axis=0).dropna(how="all", axis=1)
    if df_dna.isnull().sum().sum() == 0 and df_dna.size != 0:
        result.append(num)
print("The numbers that form rectangles are:", result)

您的结果如下所示:

The numbers that form rectangles are: [2, 4, 5, 7, 9]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM