gpt4 book ai didi

Find blocks of numbers in 2D numpy array(在二维NumPy数组中查找数字块)

转载 作者:bug小助手 更新时间:2023-10-25 17:06:14 26 4
gpt4 key购买 nike



Start by building the following numpy array:

首先构建以下NumPy数组:


import numpy as np
import itertools as it

a = np.array([[j for j in range(1,5)] for i in range(3)])

table = np.array(list(it.product(*a)))

which looks something like,

它看起来像是,


[[1 1 1]
[1 1 2]
[1 1 3]
....

i.e the cartesian product of three copies of array [1,2,3,4]. Next if for any of the rows, columns 1 and 2 (not 3) contain a 3 I set all elements in the next columns to 3 (for example, if a row reads [3 1 1] it becomes [3 3 3]):

即数组[1,2,3,4]的三个副本的笛卡尔乘积。接下来,如果对于任何行,列1和列2(不是3)包含3,则将下一列中的所有元素设置为3(例如,如果一行显示为[3 1 1],则变为[3 3 3]):


for row in table:
if len(np.where(row==3)[0])>0:
row[np.where(row==3)[0][0]:]=3

Next I have to identify blocks that contain 3s by storing four values: row,column where they start and row,column where they end. To do this I use yet another, unpythonic, for loop:

接下来,我必须通过存储四个值来识别包含3的块:开始的行、列和结束的行、列。要做到这一点,我使用了另一个非pythonic的for loop:


nr, nc = table.shape
blocks = []
bh = nr
for i in range(nc-1):
bh = (int)(bh/4)
for j in range((int)(nr/bh)):
temp = table[j*bh:(j+1)*bh,i:]
if temp[0,0]==3 and temp[-1,-1]==3:
blocks.append([[j*bh+1,i+1],[j*bh+bh,nc]])
temp[:,:]=0

and get,

然后得到,


[[[33, 1], [48, 3]], [[9, 2], [12, 3]], [[25, 2], [28, 3]], [[57, 2], [60, 3]]]

This is, obviously, a very inefficient way to use numpy. Can someone suggest a more pythonic way to do this?

显然,这是使用NumPy的一种非常低效的方式。有人能提出一种更具蟒蛇气息的方式吗?


更多回答

regarding "column where they end" : for the block [9, 2] the ending block is [12, 2]. The same for block [25, 2] and others. Why point to 3?

关于“它们结束的列”:对于块[9,2],结束块是[12,2]。块[25,2]和其他块也是如此。为什么指向3?

The table is 64 x 3 ; the biggest 3 block is located at (33,1),(48,3) using 1...n indexing instead of 0...n-1 ; the next 3 blocks are located at (9,2),(12,3) , (25,2),(28,3) and (57,2),(60,3). This set of numbers is going to be used in another program to generate some graphics. Look at the routine used to generate blocks of 3s to understand why all 3 blocks end up in column 3

表的大小为64 x 3;最大的3个块位于(33,1)、(48,3)处,使用1...n索引而不是0...n-1;接下来的3个块位于(9,2)、(12,3)、(25,2)、(28,3)和(57,2)、(60,3)。这组数字将在另一个程序中使用,以生成一些图形。查看用于生成3的块的例程,以了解为什么所有3个块都在第3列中结束

my note was not about your routine, but about your conceptually vague description

我的笔记不是关于你的日常生活,而是关于你概念性的模糊描述

Apologies. I was just trying to get the coordinates of the rectangular blocks of 3s.

抱歉我只是想得到3的矩形块的坐标。

优秀答案推荐

I couldn't get rid of all the loops, but at least removed the nested ones.

我无法删除所有循环,但至少删除了嵌套的循环。


a = np.array([[j for j in range(1,5)] for i in range(3)])
table = np.array(list(it.product(*a)))

def mask_approach(table):
bool_mask = table == 3
rows_of_3s, columns_of_3s = np.where(bool_mask == True)


output = []
flag = False
stop_iter = len(rows_of_3s)-1
for i, v in enumerate(rows_of_3s):
if i == stop_iter:
break
if rows_of_3s[i+1] - v <= 1:
if flag == False:
start = (v, columns_of_3s[i])
flag = True
elif flag == True:
flag = False
output.append((start, (v, columns_of_3s[i])))
return output

I am taking advantage of masks and use only bool array as it contains all the information needed for solving this problem.

我利用了掩码,并且只使用布尔数组,因为它包含了解决这个问题所需的所有信息。


My approach:

我的方法是:


%%timeit
mask_approach(table)

22.3 µs ± 485 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)

Your approach:

您的方法:


%%timeit
ted_black_approach(table)

171 µs ± 9.96 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)

As the solution certainly isn't perfect, I guess it introduces the way of reducing the problem to easier one, and it can be useful in further optimization.

由于解决方案肯定不是完美的,我猜它引入了将问题简化为更容易的方法,并且它可以在进一步的优化中有用。


更多回答

Nice one! Thanks!

干得好!谢谢!

This may not be entirely correct. From the question, the end of any block must always be 2 (or 3, in 1-based indexing). You can then do just output.append((start, (v, 2))) at the last line.

这可能并不完全正确。根据问题,任何块的结尾必须始终是2(或3,在基于1的索引中)。然后,您只需在最后一行执行output.append((start,(v,2)。

I think @Arcewirz missed the step where the input is converted to rectangular blocks of 3s when columns 1 to n-1 (but not n) contain a 3. But his routine can still be applied to the modified input.

我认为@Arcewirz错过了当列1到n-1(但不是n)包含3时,输入被转换为3的矩形块的步骤。但他的例程仍然可以应用于修改后的输入。

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com