目录

零、前言提要

一、参考来源和基础知识小结

二、求取容器中的最大值、最小值

2.1 python内置的max()函数

2.2 numpy模块的np.max函数(同np.amax)、np.nanmax函数

2.3 numpy模块的np.maximum()函数

2.4 numpy模块的np.fmax函数

三、求取最大值、最小值的索引(所处位置)


零、前言提要

本篇文章基于py3.8,system win10,numpy1.12。

np是numpy的缩写。

一、参考来源和基础知识小结

python内置max()、min()函数与Numpy自带的max()、min()函数性能对比分析

上面这篇文章基于python 2.7.15,system win10得出结论:python内置的max()运行速度优于numpy模块,但是使用的方便性和灵活性上numpy.max更佳。

numpy 学习汇总36- max,amax,nanmax,fmax,maximum的区别

上面这篇文章给的传播NAN和忽略NAN的概念是指“在运算过程中遇到NAN是直接把结果确立为NAN还是直接忽略NAN”。例如sum()函数默认是传播NAN的,那么sum([1,2,np.nan])的结果就是nan。而np.nansum()函数默认是忽略NAN的,因此np.nansum([1,2,np.nan])的结果是3。

二、求取容器中的最大值、最小值

下面全部以求最大值为例,最小值的效果和它是对称的。

除了求最大值是遇到Inf就捡起来,而求最大值是遇到Inf就丢掉,其他基本一样,就不赘述了。

2.1 python内置的max()函数

功能简介:求解可迭代对象的最大值或者多个参数的最大值

# 1 语法一:只有一个容器
    max(iterable, *[, key, default])

# 1.1 容器是列表、数组、元组、集合、字符串
import numpy as np
print(max([1,2,3]))  # 输出结果3
print(max(np.array([1,2,3])))  # 输出结果3
print(max((1,2,3)))  # 输出结果3
print(max({1,2,3}))  # 输出结果3
print(max('I love you, my girl.'))  # 输出为y

# 1.2 多维容器和多层嵌套
print(max([[1, 2], [3, 4]]))  # 列表形状(2,2),输出为[3, 4],说明列表是在最外一层进行比较
print(max([[[1, 2], [3, 4]]]))  # 列表形状(1,2,2),输出[[1, 2], [3, 4]],再次验证...
print(max((((1, 2, 3)),((2,3,4)))))  # 元组形状为(2,1,3),输出(2, 3, 4)
print(max(((((1, 2, 3)),((2,3,4))))))  # 元组形状为(1,2,1,3),还是输出(2, 3, 4),说明对于元组会把多余的括号去掉

#1.3 key参数用法,规定在容器的哪个位置/属性之间进行比较
print(max([{'name':'zhang','age':13},{'name':'shen','age':56}],key=lambda x:x['age']))  # 输出为{'name': 'shen', 'age': 56}

#1.4 default参数用法,规定如果得不出最大值就返回default默认值,用来避免出错
print(max((),default=1))  # 输出为1
print(max(()))  # 传入空元组,无法得出最大值,错误ValueError: max() arg is an empty sequence

#1.5 如果仅传入一个可比较参数,并且这个参数不是容器,就会报错
print(max(1))  # TypeError: 'int' object is not iterable
print(max(1.3))  # TypeError: 'float' object is not iterable

#-------------------------
# 2、语法二:传入多个参数(既可以是单个数值,也可以是容器)
    max(arg1, arg2, *args[, key])    

# 2.1 传入多个单独的数值
print(max(1,2,3,4,5,6))  # 输出为6

# 2.2 传入多个容器
print(max([1,2],[3,4],[6,-9999]))  # 输出为[6, -9999],说明仅仅比较第一个数
print(max([[1,2],[3,4]],[[0,5],[6,7]]))  # 输出为[[1, 2], [3, 4]],说明只比较第一个数

# 2.3 在多个参数之间用key
print(max({'name':'zhang','age':13},{'name':'shen','age':56},key=lambda x:x['age']))  # 输出为{'name': 'shen', 'age': 56}

#--------------------------
# 3、其他注意事项

# 3.1 千万不要加参数axis,因为内置的max函数没有这个参数

# 3.2 内置的max()函数会传播nan,而numpy.nanmax()可以避开nan
print(max([np.nan,1,2,3]))  # 输出为nan,说明内置max函数会传播nan
print(np.nanmax([np.nan,1,2,3]))  # 3.0

2.2 numpy模块的np.max函数(同np.amax)、np.nanmax函数

import numpy as np

# 1、np.max实际上就是np.amax
np.max.__name__        # 'amax'
np.max is np.amax      # True
np.amax                # <function numpy.core.fromnumeric.amax>
np.max                 # <function numpy.core.fromnumeric.amax>

# 2、语法
    np.amax(array_like, axis=None, out=None, keepdims=<no value>, initial=<no value>)

    2.1 array_like:可以是数组,也可以是和数组相似的容器(元组、列表),只能传一个这种参数
    2.2 axis:这是python内置max()没有的参数,用来指定在哪个维度上比较
    2.3 keepdims:是否保留维数
    2.4 只要包括nan,就返回nan,也即传播nan。
    2.5 只要包括Inf,就返回Inf,因为Inf是正无穷大。

# 3、实例

# 3.1 当axis=None时,对所有数进行比较得到一个最大值
print(np.max([12, 34]))  # 34
print(np.max([[12, 34], [56, 78]]))  # 结果是78而不是[56,78],说明不指定axis=None时是将所有维度下的成员进行比较,最终返回一个最大值
print(np.max([[[[[[12, 34], [56, 78]]]]]]))  # 输出78,说明不管嵌套多少层,都是返回最大的那个元素,这也是跟内置max()不一样的地方

# 3.2 当axis!=x(一个整数)时,在指定维度上比较
print(np.max([[12, 34], [10, 78]], axis=0))  # [12 78]
print(np.max([[12, 34], [10, 78]], axis=1))  # [34 78]

# 3.3 当keepdims=True时,axis指定的那个维度不会归零化
print(np.max([[12, 34], [10, 78]], axis=0, keepdims=True))  # [[12 78]]
print(np.max([[12, 34], [10, 78]], axis=1, keepdims=True))  # [[34], [78]]

 至于np.nanmax,除了会忽视nan,其他特性与np.max()、np.amax()相同。

除了利用numpy模块里的函数求最大值,也可以用ndarray数组的max属性求最大值。

import numpy as np

arr = np.arange(9).reshape(3,3)

print(arr.max(0))  # [6, 7, 8],参数0表示axis=0

用法和numpy.max()函数大致相同,只不过是把array参数提到max前面了。

此外要注意这种方法不能对非ndarray数组对象求最大值,因为list\tuple\set这些容器没有这个属性。

2.3 numpy模块的np.maximum()函数

# 1、语法
    np.maximum(X, Y, out=None)
   
# 2、简介
    # 2.1 X和Y逐位进行比较,选择最大值,必须接受两个进行比较的对象,多了少了都不行
    # 2.2 会传播NAN;如果存在Inf直接返回Inf

# 3、代码实现
>>> np.maximum([2, 3, 4], [1, 5, 2])
array([2, 5, 4])

>>> np.maximum(np.eye(2), [0.5, 2]) # broadcasting
array([[ 1. ,  2. ],
       [ 0.5,  2. ]])
       
>>> np.maximum([np.nan, 0, np.nan], [0, np.nan, np.nan])
array([ NaN,  NaN,  NaN])

>>> np.maximum(np.Inf, 1)
inf

2.4 numpy模块的np.fmax函数

np.fmax函数和np.maximum函数辨析:

2.4.1共同点:

        (1)都是对两个参数中的元素值进行比较,最终返回位置对应的最大值。

        (2)都可以用broadcast机制。

        (3)都必须只传入两个比较对象,多了少了都会报错

        (4)都是ufunc函数,可以配合accumulate,reduce,reduceat等属性使用。

          第4点欲知如何请见:https://blog.csdn.net/tcy23456/article/details/84589554

2.4.2差异点:np.fmax会忽略NAN,而np.maximum会传播NAN。记忆技巧:f是forget,把nan给忘了,不认识它是谁,直接忽略掉了。

import numpy as np

# 1、语法
    np.fmax(x1, x2)

# 2、简介
    # 2.1 x1和x2分别是一个数值或者一个容器(数组、列表、元组),逐个元素地进行比较在每一个位置返回最大的值(浮点型),
    # 2.2 会忽略NAN,但是如果两个数都是NAN,就会返回NAN;一旦某位置有Inf,必返回Inf
    # 2.3 必须接受两个进行比较的对象,多了少了都报错

# 3、实现代码
# 3.1 传入两个数
print(np.fmax(1, 3))  # 3
print(np.fmax(1, 3, 2, 4, 5, 6))  #TypeError: fmax() takes from 2 to 3 positional arguments but 6 were given

# 3.2 容器中有nan,能避就避,避不了才用;容器中有Inf,必须用
print(np.fmax([1,np.nan],[2,999]))  # [ 2. 999.]
print(np.fmax([1,np.nan],[2,np.nan]))  # [ 2. nan]
print(np.fmax([1,np.Inf],[2,999]))  # [ 2. inf]

三、求取最大值、最小值的索引(所处位置)

 本文的第二部分都是在求一个容器中的最大值,或者两个容器之间进行逐个比较取更大值。

下面的np.argmax并不是求最大值本身,而是求最大值在哪个位置(也即索引值)。

import numpy as np

# 1、语法
    np.argmax(array_like, axis=None, out=None, *, keepdims=np._NoValue)
    
# 2、代码实现
# 2.1 说明如果有多个数值相同,返回先出现的索引值
print(np.argmax([1,2,3,4,4,4,4,4]))  # 3
print(np.argmax([[1,2],[3,2]], axis=0))  # [1 0]

# 2.1 axis=None的时候,只会返回一个索引值(python中默认的索引顺序为C,也即先行后列,先里层后外层)
print(np.argmax(np.arange(9).reshape(3,3)))  #8

# 2.2 axis=x(一个整数)时,就会在这个维度上逐个元素进行比较,比如x=0,那么就是a[0]、a[1]、...、a[len(a)-1]之间进行比较
print(np.argmax(np.arange(9).reshape(3,3), axis=0))  #[2 2 2]。当axis=0,在第0维进行比较,也即比较a[0,0]、a[1,0]和a[2,0]

# 2.3 keepdims=True时,a[0]、a[1]、...、a[len(a)-1]之间比较得到的最大值索引外的中括号不丢掉,因此维度保留
print(np.argmax(np.arange(9).reshape(3,3), axis=0, keepdims=True))  #[[2 2 2]]。
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐