目录
零、前言提要
一、参考来源和基础知识小结
二、求取容器中的最大值、最小值
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就丢掉,其他基本一样,就不赘述了。
功能简介:求解可迭代对象的最大值或者多个参数的最大值
# 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
import numpy as np
# 1、np.max实际上就是np.amax
np.max.__name__ # 'amax'
np.max is np.amax # True
np.amax #
np.max #
# 2、语法
np.amax(array_like, axis=None, out=None, keepdims=, initial=)
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这些容器没有这个属性。
# 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
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]]。