python找出数组最大值函数_python – 查找2-D numpy数组的相对最大值

我有一个2-D numpy数组,可以细分为64个盒子(想象棋盘).

目标是返回每个框中最大值的位置和值的函数.就像是:

FindRefs(array) --> [(argmaxX00, argmaxY00, Max00), ...,(argmaxX63, argmaxY63, Max63)]

其中argmaxXnn和argmaxYnn是整个数组的索引(不是框的索引),Maxnn是每个框中的最大值.换一种说法,

Maxnn = array[argmaxYnn,argmaxYnn]

我尝试了明显的“嵌套式”解决方案:

def FindRefs(array):

Height, Width = array.shape

plumx = []

plumy = []

lum = []

w = int(Width/8)

h = int(Height/8)

for n in range(0,8): # recorrer boxes

x0 = n*w

x1 = (n+1)*w

for m in range(0,8):

y0 = m*h

y1 = (m+1)*h

subflatind = a[y0:y1,x0:x1].argmax() # flatten index of box

y, x = np.unravel_index(subflatind, (h, w))

X = x0 + x

Y = y0 + y

lum.append(a[Y,X])

plumx.append(X)

plumy.append(Y)

refs = []

for pt in range(0,len(plumx)):

ptx = plumx[pt]

pty = plumy[pt]

refs.append((ptx,pty,lum[pt]))

return refs

它有效,但既不优雅也不高效.

所以我尝试了这个更pythonic版本:

def FindRefs(a):

box = [(n*w,m*h) for n in range(0,8) for m in range(0,8)]

flatinds = [a[b[1]:h+b[1],b[0]:w+b[0]].argmax() for b in box]

unravels = np.unravel_index(flatinds, (h, w))

ur = [(unravels[1][n],unravels[0][n]) for n in range(0,len(box))]

absinds = [map(sum,zip(box[n],ur[n])) for n in range(0,len(box))]

refs = [(absinds[n][0],absinds[n][1],a[absinds[n][1],absinds[n][0]]) for n in range(0,len(box))]

return refs

它工作正常,但令我惊讶的是,它并不比以前的版本更有效!

问题是:有没有更聪明的方法来完成任务?

请注意,效率很重要,因为我有许多用于处理的大型数组.

任何线索都是受欢迎的. 🙂

最佳答案 试试这个:

from numpy.lib.stride_tricks import as_strided as ast

import numpy as np

def FindRefs3(a):

box = tuple(x/8 for x in a.shape)

z=ast(a, \

shape=(8,8)+box, \

strides=(a.strides[0]*box[0],a.strides[1]*box[1])+a.strides)

v3 = np.max(z,axis=-1)

i3r = np.argmax(z,axis=-1)

v2 = np.max(v3,axis=-1)

i2 = np.argmax(v3,axis=-1)

i2x = np.indices(i2.shape)

i3 = i3r[np.ix_(*[np.arange(x) for x in i2.shape])+(i2,)]

i3x = np.indices(i3.shape)

ix0 = i2x[0]*box[0]+i2

ix1 = i3x[1]*box[1]+i3

return zip(np.ravel(ix0),np.ravel(ix1),np.ravel(v2))

请注意,您的第一个FindRefs会反转索引,因此对于元组(i1,i2,v),[i1,i2]将不会返回正确的值,而[i2,i1]将返回.

所以代码的作用如下:

>首先根据数组的大小计算每个盒子需要的尺寸(方框).请注意,这不会进行任何检查:您需要一个可以均匀分配到8乘8网格的数组.

>然后z与ast是最混乱的一点.它采用2d阵列,并将其转换为4d阵列. 4d数组有尺寸(8,8,方框[0],方框[1]),因此它可以让你选择你想要的盒子(前两个轴),然后选择你想要的盒子位置(接下来的两个) .这使我们可以通过在最后两个轴上进行操作来一次处理所有框.

> v3给出了最后一个轴的最大值:换句话说,它包含每个框中每列的最大值. i3r包含框中哪一行包含该最大值的索引.

> v2沿着它自己的最后一个轴取最大值v3,它现在处理框中的行:它取最大列,并找到它们的最大值,这样v2就是一个包含每个框最大值的二维数组.如果您想要的只是最大值,那么这就是您所需要的.

> i2是包含最大值的框中列的索引.

>现在我们需要获取框中行的索引……这比较棘手. i3r包含框中每列最大行的索引,但我们想要在i2中指定的特定列的行.我们通过使用i2从i3r中选择一个元素来实现这一点,它给了我们i3.

>此时,i2和i3是8乘8的数组,包含相对于每个框的最大值的行索引和列索引.我们想要绝对指数.所以我们创建i2x和i3x(实际上,这是毫无意义的;我们可以创建一个,因为它们是相同的),它们只是i2和i3的索引的数组(0,1,2,…, 8等在一个维度上,等等).然后我们将它们乘以框大小,并添加相对最大索引,以获得绝对最大索引.

>然后我们将这些组合起来以获得与您相同的输出.请注意,如果将它们保留为数组,而不是制作元组,则速度要快得多.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值