A key in numpy.amax

。_饼干妹妹 提交于 2021-02-10 07:49:05

问题


In the Python's standard max function I can pass in a key parameter:

s = numpy.array(['one','two','three'])
max(s) # 'two' (lexicographically last)
max(s, key=len) # 'three' (longest string)

With a larger (multi-dimensional) array, we can not longer use max, but we can use numpy.amax... which unfortunately offers no key parameter.

t = numpy.array([['one','two','three'],
                 ['four','five','six']], 
                dtype='object')
numpy.amax(t) # 'two` (max of the flat array)
numpy.amax(t, axis=1) # array([two, six], dtype=object) (max of first row, followed by max of second row)

What I want to be able to do is:

amax2(t, key=len) # 'three'
amax2(t, key=len, axis=1) # array([three, four], dtype=object)

Is there a built-in method to do this?

Note: In trying to write this question the first time I couldn't get amax working in this toy example!


回答1:


This is a non built-in way (it's missing the out and keepdim parameters of features of amax when using key), it seems rather long:

def amax2(x, *args, **kwargs):
    if 'key' not in kwargs:
        return numpy.amax(x,*args,**kwargs)
    else:
        key = kwargs.pop('key') # e.g. len, pop so no TypeError: unexpected keyword
        x_key = numpy.vectorize(key)(x) # apply key to x element-wise
        axis = kwargs.get('axis') # either None or axis is set in kwargs
        if len(args)>=2: # axis is set in args
            axis = args[1]

        # The following is kept verbose, but could be made more efficient/shorter    
        if axis is None: # max of flattened
            max_flat_index = numpy.argmax(x_key, axis=axis)
            max_tuple_index = numpy.unravel_index(max_flat_index, x.shape)
            return x[max_tuple_index]
        elif axis == 0: # max in each column
            max_indices = numpy.argmax(x_key, axis=axis)
            return numpy.array(
                 [ x[max_i, i] # reorder for col
                     for i, max_i in enumerate(max_indices) ], 
                 dtype=x.dtype)
        elif axis == 1: # max in each row
            max_indices = numpy.argmax(x_key, axis=axis)
            return numpy.array(
                 [ x[i, max_i]
                     for i, max_i in enumerate(max_indices) ],
                 dtype=x.dtype)

The idea for this function is extended from the second part of @PeterSobot's answer to my previous question.



来源:https://stackoverflow.com/questions/12655525/a-key-in-numpy-amax

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!