NumPy 之 max
函数详解与示例
NumPy 是 Python 中用于科学计算的核心库,提供了高性能的多维数组对象和用于处理这些数组的工具。在数据分析和科学计算中,查找数据集中的最大值是一项基本且常用的操作。NumPy 提供了 max
函数(以及其别名 amax
和数组方法 .max()
)来实现这一功能。
本文将详细介绍 NumPy 中 max
函数的各种用法,包括其基本功能、关键参数(如 axis
、keepdims
、out
、initial
和 where
)、与相关函数的区别(如 np.maximum
和 np.nanmax
),并通过丰富的示例来帮助读者深入理解。
1. numpy.max
的基本概念
numpy.max(a, axis=None, out=None, keepdims=<no value>, initial=<no value>, where=<no value>)
这个函数的主要目的是找到一个数组(或数组中的指定维度)的最大值。
- 输入
a
: 这是一个必需的参数,表示需要进行最大值查找的输入数组(可以是ndarray
或类似数组的对象,如 Python 列表、元组等)。 - 返回值: 函数返回输入数组或指定维度上的最大值。返回值的形状取决于
axis
和keepdims
参数。
最简单的用法是查找整个数组的最大值。
示例 1.1:查找一维数组的最大值
“`python
import numpy as np
arr1 = np.array([1, 5, 2, 8, 3, 9, 4])
max_value1 = np.max(arr1)
print(f”一维数组: {arr1}”)
print(f”一维数组的最大值: {max_value1}”)
也可以直接用于列表或元组(NumPy会自动转换为数组)
list1 = [10, 2, 7, 15, 4]
max_value_list = np.max(list1)
print(f”列表: {list1}”)
print(f”列表的最大值: {max_value_list}”)
“`
输出:
一维数组: [1 5 2 8 3 9 4]
一维数组的最大值: 9
列表: [10, 2, 7, 15, 4]
列表的最大值: 15
示例 1.2:查找多维数组的整体最大值
当 axis
参数为 None
(默认值)时,np.max
会将多维数组展平,然后查找展平后的所有元素的最大值。
“`python
import numpy as np
arr2 = np.array([[1, 5, 2],
[8, 3, 9],
[4, 6, 7]])
max_value2 = np.max(arr2) # axis=None is default
print(f”二维数组:\n{arr2}”)
print(f”二维数组的整体最大值: {max_value2}”)
“`
输出:
二维数组:
[[1 5 2]
[8 3 9]
[4 6 7]]
二维数组的整体最大值: 9
2. 理解 axis
参数
axis
参数是 np.max
中最重要的参数之一,它决定了函数沿哪个轴(维度)进行最大值查找。当沿着某个轴计算最大值时,该轴将被“压缩”或“消失”,结果数组的维度会比原数组少一个。
- 对于二维数组(例如 shape 为
(rows, cols)
):axis=0
: 沿垂直方向(行)计算最大值,结果是一个一维数组,其长度等于列数 (cols
)。可以理解为查找每一列的最大值。axis=1
: 沿水平方向(列)计算最大值,结果是一个一维数组,其长度等于行数 (rows
)。可以理解为查找每一行的最大值。
- 对于三维数组(例如 shape 为
(dim0, dim1, dim2)
):axis=0
: 沿第一个轴计算最大值,结果的 shape 为(dim1, dim2)
。axis=1
: 沿第二个轴计算最大值,结果的 shape 为(dim0, dim2)
。axis=2
: 沿第三个轴计算最大值,结果的 shape 为(dim0, dim1)
。axis
也可以是轴的列表或元组,表示沿这些轴同时计算最大值。结果数组将丢失这些轴对应的维度。
示例 2.1:二维数组按列 (axis=0
) 计算最大值
“`python
import numpy as np
arr3 = np.array([[1, 5, 2],
[8, 3, 9],
[4, 6, 7]])
axis=0: 沿行方向计算,结果每列一个最大值
第一列 [1, 8, 4] 的最大值是 8
第二列 [5, 3, 6] 的最大值是 6
第三列 [2, 9, 7] 的最大值是 9
max_by_column = np.max(arr3, axis=0)
print(f”二维数组:\n{arr3}”)
print(f”按列计算最大值 (axis=0): {max_by_column}”)
print(f”结果形状: {max_by_column.shape}”)
“`
输出:
二维数组:
[[1 5 2]
[8 3 9]
[4 6 7]]
按列计算最大值 (axis=0): [8 6 9]
结果形状: (3,)
示例 2.2:二维数组按行 (axis=1
) 计算最大值
“`python
import numpy as np
arr4 = np.array([[1, 5, 2],
[8, 3, 9],
[4, 6, 7]])
axis=1: 沿列方向计算,结果每行一个最大值
第一行 [1, 5, 2] 的最大值是 5
第二行 [8, 3, 9] 的最大值是 9
第三行 [4, 6, 7] 的最大值是 7
max_by_row = np.max(arr4, axis=1)
print(f”二维数组:\n{arr4}”)
print(f”按行计算最大值 (axis=1): {max_by_row}”)
print(f”结果形状: {max_by_row.shape}”)
“`
输出:
二维数组:
[[1 5 2]
[8 3 9]
[4 6 7]]
按行计算最大值 (axis=1): [5 9 7]
结果形状: (3,)
示例 2.3:三维数组按不同轴计算最大值
“`python
import numpy as np
arr5 = np.arange(24).reshape(2, 3, 4)
print(f”三维数组 (shape {arr5.shape}):\n{arr5}”)
axis=0: 沿第一个维度(层)计算最大值
结果 shape (3, 4)
max_axis0 = np.max(arr5, axis=0)
print(f”\n按 axis=0 计算最大值 (shape {max_axis0.shape}):\n{max_axis0}”)
比较 arr5[0, i, j] 和 arr5[1, i, j],取较大值
axis=1: 沿第二个维度(行)计算最大值
结果 shape (2, 4)
max_axis1 = np.max(arr5, axis=1)
print(f”\n按 axis=1 计算最大值 (shape {max_axis1.shape}):\n{max_axis1}”)
对于 arr5[k, :, j],即 arr5[:, :, j] 在维度1上的最大值
axis=2: 沿第三个维度(列)计算最大值
结果 shape (2, 3)
max_axis2 = np.max(arr5, axis=2)
print(f”\n按 axis=2 计算最大值 (shape {max_axis2.shape}):\n{max_axis2}”)
对于 arr5[k, i, :],即 arr5[k, i, :] 在维度2上的最大值
axis=(0, 1): 沿前两个维度计算最大值
结果 shape (4,)
max_axis01 = np.max(arr5, axis=(0, 1))
print(f”\n按 axis=(0, 1) 计算最大值 (shape {max_axis01.shape}):\n{max_axis01}”)
axis=None: 展平并计算整体最大值
结果 shape () – 标量
max_axis_none = np.max(arr5, axis=None)
print(f”\n按 axis=None 计算最大值 (shape {max_axis_none.shape}): {max_axis_none}”)
“`
理解 axis
参数的关键在于记住它是“执行操作并压缩掉的那个轴”。
3. keepdims
参数:保留维度
keepdims
参数是一个布尔值(True 或 False),默认情况下,当指定 axis
进行最大值计算时,结果数组会丢失被压缩的维度。设置 keepdims=True
可以保留这些维度,但它们的大小会变为 1。这在进行广播操作时非常有用,因为保留维度为 1 的轴可以参与广播。
示例 3.1:axis=0
带 keepdims=True
“`python
import numpy as np
arr6 = np.array([[1, 5, 2],
[8, 3, 9],
[4, 6, 7]])
max_by_column_kept = np.max(arr6, axis=0, keepdims=True)
print(f”二维数组:\n{arr6}”)
print(f”按列计算最大值 (axis=0, keepdims=True): {max_by_column_kept}”)
print(f”结果形状: {max_by_column_kept.shape}”)
“`
输出:
二维数组:
[[1 5 2]
[8 3 9]
[4 6 7]]
按列计算最大值 (axis=0, keepdims=True): [[8 6 9]]
结果形状: (1, 3)
注意结果的形状是 (1, 3)
,而不是 (3,)
。这使得结果可以方便地与原数组进行广播操作,例如:
“`python
将每一行的元素减去该列的最大值(示例,实际意义不大,但演示广播)
原数组形状 (3, 3), 结果形状 (1, 3)
(3, 3) – (1, 3) -> (3, 3) 可以广播
subtracted = arr6 – max_by_column_kept
print(f”\n原数组减去各列最大值 (广播示例):\n{subtracted}”)
“`
输出:
原数组减去各列最大值 (广播示例):
[[-7 -1 -7]
[ 0 -3 0]
[-4 0 -2]]
如果没有 keepdims=True
,max_by_column
的形状是 (3,)
,与 arr6
(3, 3)
形状不兼容,直接相减会报错(或者需要额外的 reshape 操作)。
示例 3.2:axis=1
带 keepdims=True
“`python
import numpy as np
arr7 = np.array([[1, 5, 2],
[8, 3, 9],
[4, 6, 7]])
max_by_row_kept = np.max(arr7, axis=1, keepdims=True)
print(f”二维数组:\n{arr7}”)
print(f”按行计算最大值 (axis=1, keepdims=True):\n{max_by_row_kept}”)
print(f”结果形状: {max_by_row_kept.shape}”)
“`
输出:
二维数组:
[[1 5 2]
[8 3 9]
[4 6 7]]
按行计算最大值 (axis=1, keepdims=True):
[[5]
[9]
[7]]
结果形状: (3, 1)
结果形状是 (3, 1)
。这使得结果可以方便地与原数组进行广播操作,例如:
“`python
将每一行的元素除以该行的最大值
原数组形状 (3, 3), 结果形状 (3, 1)
(3, 3) / (3, 1) -> (3, 3) 可以广播
divided = arr7 / max_by_row_kept
print(f”\n原数组除以各行最大值 (广播示例):\n{divided}”)
“`
输出:
原数组除以各行最大值 (广播示例):
[[0.2 1. 0.4 ]
[0.88888889 0.33333333 1. ]
[0.57142857 0.85714286 1. ]]
4. out
参数:指定输出数组
out
参数允许你提供一个现有的数组作为存储结果的位置。这在需要重复执行最大值计算并将结果存入同一个预先分配的数组时非常有用,可以避免不必要的内存分配和释放,从而提高效率。指定 out
数组时,它的形状和数据类型必须与期望的输出结果兼容。
示例 4.1:使用 out
参数
“`python
import numpy as np
arr8 = np.array([[1, 5, 2],
[8, 3, 9],
[4, 6, 7]])
计算按列的最大值,期望结果形状 (3,)
out_array = np.empty(3, dtype=arr8.dtype)
np.max(arr8, axis=0, out=out_array)
print(f”二维数组:\n{arr8}”)
print(f”使用 out 参数存储的按列最大值: {out_array}”)
print(f”存储数组的形状: {out_array.shape}”)
计算整体最大值,期望结果是标量,out数组形状应为空或 (1,)
out_scalar = np.empty((), dtype=arr8.dtype) # 创建一个形状为空的数组
out_scalar = np.array(0, dtype=arr8.dtype) # 更简单的方式
np.max(arr8, out=out_scalar)
print(f”使用 out 参数存储的整体最大值: {out_scalar}”)
print(f”存储数组的形状: {out_scalar.shape}”)
注意:如果 out 数组形状不匹配,会报错
wrong_out_array = np.empty((2,), dtype=arr8.dtype)
np.max(arr8, axis=0, out=wrong_out_array) # 这行会报错 Shape-mismatch
“`
使用 out
参数通常在性能敏感的代码块中,例如在循环内重复计算并更新同一个结果数组。
5. initial
参数:设置起始值
initial
参数允许你为最大值计算设置一个起始值。这在某些特定情况下很有用,特别是当结合 where
参数使用或者处理空数组时。
- 如果数组为空,并且没有指定
initial
,np.max
会引发ValueError
。 - 如果指定了
initial
,并且数组为空或者所有被where
条件排除的元素都被排除后数组为空,那么initial
值将作为结果返回。 - 在计算过程中,如果数组中的所有有效元素都小于
initial
,那么initial
将是最终结果。
示例 5.1:空数组与 initial
“`python
import numpy as np
empty_arr = np.array([], dtype=int)
try:
max_empty = np.max(empty_arr)
print(f”空数组的最大值 (无 initial): {max_empty}”)
except ValueError as e:
print(f”查找空数组的最大值 (无 initial) 报错: {e}”)
max_empty_with_initial = np.max(empty_arr, initial=-999)
print(f”空数组的最大值 (有 initial -999): {max_empty_with_initial}”)
max_empty_with_initial_large = np.max(empty_arr, initial=100)
print(f”空数组的最大值 (有 initial 100): {max_empty_with_initial_large}”)
“`
输出:
查找空数组的最大值 (无 initial) 报错: zero-size array to reduction operation maximum which has no identity
空数组的最大值 (有 initial -999): -999
空数组的最大值 (有 initial 100): 100
示例 5.2:结合 where
和 initial
结合 where
参数时,initial
的作用更加明显。如果 where
条件导致没有任何元素被包含在计算中,initial
值将作为结果。
“`python
import numpy as np
arr9 = np.array([10, 20, 5, 15, 30])
where_mask = np.array([False, False, False, False, False]) # 所有元素都被排除
所有元素都被排除,无 initial
try:
max_where_no_initial = np.max(arr9, where=where_mask)
print(f”where条件为全False (无 initial): {max_where_no_initial}”)
except ValueError as e:
print(f”where条件为全False (无 initial) 报错: {e}”)
所有元素都被排除,有 initial
max_where_with_initial = np.max(arr9, where=where_mask, initial=-np.inf) # 使用负无穷大作为通用起始值
print(f”where条件为全False (有 initial -inf): {max_where_with_initial}”)
部分元素被包含
where_mask_partial = np.array([False, True, False, True, False]) # 包含 20 和 15
max_where_partial_no_initial = np.max(arr9, where=where_mask_partial)
print(f”where条件部分为True (无 initial): {max_where_partial_no_initial}”)
部分元素被包含,设置一个比所有被包含元素都大的 initial
max_where_partial_with_initial = np.max(arr9, where=where_mask_partial, initial=100)
print(f”where条件部分为True (有 initial 100): {max_where_partial_with_initial}”) # 100 > max(20, 15)
部分元素被包含,设置一个比所有被包含元素都小的 initial
max_where_partial_with_small_initial = np.max(arr9, where=where_mask_partial, initial=0)
print(f”where条件部分为True (有 initial 0): {max_where_partial_with_small_initial}”) # max(0, 20, 15) = 20
“`
输出:
where条件为全False (无 initial) 报错: zero-size array to reduction operation maximum which has no identity
where条件为全False (有 initial -inf): -inf
where条件部分为True (无 initial): 20
where条件部分为True (有 initial 100): 100
where条件部分为True (有 initial 0): 20
initial
参数在使用 where
过滤元素时提供了处理“无有效元素”情况的灵活方式。
6. where
参数:条件查找最大值
where
参数允许你只在满足指定条件的数组元素中查找最大值。它是一个与输入数组 a
广播兼容的布尔数组。只有 where
数组中对应位置为 True
的元素才会被考虑进行最大值计算。
当 where
条件为 False
的位置,NumPy 会使用一个“无关紧要”的值(对于最大值通常是一个非常小的值,例如数据类型的最小值或 -np.inf
)来填充,以确保计算的正确性,而不会影响最终结果。
示例 6.1:使用 where
参数
“`python
import numpy as np
arr10 = np.array([10, 20, 5, -15, 30, 8, -25])
查找大于 0 的元素中的最大值
where_positive = arr10 > 0
print(f”原始数组: {arr10}”)
print(f”where条件 (大于0): {where_positive}”) # [ True True True False True True False]
max_positive = np.max(arr10, where=where_positive)
print(f”大于 0 的元素中的最大值: {max_positive}”) # 在 [10, 20, 5, 30, 8] 中找最大值
查找小于 10 的元素中的最大值
where_less_than_10 = arr10 < 10
print(f”where条件 (小于10): {where_less_than_10}”) # [False False True True False False True]
max_less_than_10 = np.max(arr10, where=where_less_than_10)
print(f”小于 10 的元素中的最大值: {max_less_than_10}”) # 在 [5, -15, -25] 中找最大值
结合 axis 和 where
arr11 = np.array([[1, 5, 2],
[8, 3, 9],
[4, 6, 7]])
查找每行中大于 3 的元素的最大值
where_greater_than_3 = arr11 > 3
print(f”\n二维数组:\n{arr11}”)
print(f”where条件 (大于3):\n{where_greater_than_3}”)
axis=1: 按行计算
第一行: [1, 5, 2],条件 [False, True, False],有效元素 [5],最大值 5
第二行: [8, 3, 9],条件 [True, False, True],有效元素 [8, 9],最大值 9
第三行: [4, 6, 7],条件 [True, True, True],有效元素 [4, 6, 7],最大值 7
max_row_where = np.max(arr11, axis=1, where=where_greater_than_3)
print(f”按行计算大于 3 的元素的最大值 (axis=1):\n{max_row_where}”)
axis=0: 按列计算
第一列: [1, 8, 4],条件 [False, True, True],有效元素 [8, 4],最大值 8
第二列: [5, 3, 6],条件 [True, False, True],有效元素 [5, 6],最大值 6
第三列: [2, 9, 7],条件 [False, True, True],有效元素 [9, 7],最大值 9
max_col_where = np.max(arr11, axis=0, where=where_greater_than_3)
print(f”按列计算大于 3 的元素的最大值 (axis=0):\n{max_col_where}”)
“`
输出:
“`
原始数组: [ 10 20 5 -15 30 8 -25]
where条件 (大于0): [ True True True False True True False]
大于 0 的元素中的最大值: 30
where条件 (小于10): [False False True True False False True]
小于 10 的元素中的最大值: 5
二维数组:
[[1 5 2]
[8 3 9]
[4 6 7]]
where条件 (大于3):
[[False True False]
[ True False True]
[ True True True]]
按行计算大于 3 的元素的最大值 (axis=1):
[5 9 7]
按列计算大于 3 的元素的最大值 (axis=0):
[8 6 9]
“`
当 where
条件导致某个维度的所有元素都被排除时(例如,计算某行的最大值,但该行的 where
条件全部为 False
),如果没有指定 initial
,该维度的结果将引发 ValueError
。如果指定了 initial
,则该维度的结果将是 initial
值。
示例 6.2:where
条件全为 False 的情况与 initial
“`python
import numpy as np
arr12 = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
where_mask_row2_false = np.array([[True, True, True],
[False, False, False], # 这一行所有元素被排除
[True, True, True]])
print(f”二维数组:\n{arr12}”)
print(f”where条件:\n{where_mask_row2_false}”)
按行计算 (axis=1)
try:
max_row_where_false = np.max(arr12, axis=1, where=where_mask_row2_false)
print(f”按行计算 (where第二行全False,无initial):\n{max_row_where_false}”)
except ValueError as e:
print(f”按行计算 (where第二行全False,无initial) 报错: {e}”)
max_row_where_false_initial = np.max(arr12, axis=1, where=where_mask_row2_false, initial=-99)
print(f”按行计算 (where第二行全False,有initial -99):\n{max_row_where_false_initial}”)
“`
输出:
二维数组:
[[1 2 3]
[4 5 6]
[7 8 9]]
where条件:
[[ True True True]
[False False False]
[ True True True]]
按行计算 (where第二行全False,无initial) 报错: zero-size array to reduction operation maximum which has no identity
按行计算 (where第二行全False,有initial -99): [ 3 -99 9]
可以看到,在第二行(索引为 1)的计算中,由于 where
条件全为 False
且没有 initial
,引发了错误。当提供了 initial=-99
后,第二行的结果变成了 -99
。
7. np.max
、np.amax
与 array.max()
NumPy 提供了几种方式来执行最大值计算:
numpy.max(a, ...)
: 作为 NumPy 模块的函数。numpy.amax(a, ...)
: 这是numpy.max
的一个别名。在旧版本的 NumPy 或某些文档中可能会看到amax
,它们的功能是相同的。array.max(axis=None, out=None, keepdims=False)
: 作为ndarray
对象的方法。
区别:
- 调用方式: 函数形式 (
np.max
或np.amax
) 将数组作为第一个参数传入,而方法形式 (array.max()
) 是直接在数组对象上调用的。 - 参数: 方法形式的
max
参数略少,它不支持initial
和where
参数。 keepdims
默认值: 函数形式 (np.max
) 的keepdims
默认值是一个特殊标记<no value>
,表示其行为会根据是否指定axis
而定(如果指定axis
则默认为False
,否则为False
但行为类似True
对于标量输出)。方法形式 (array.max()
) 的keepdims
默认值为False
。通常建议显式指定keepdims=True
或False
以避免混淆。
示例 7.1:函数形式 vs 方法形式
“`python
import numpy as np
arr13 = np.array([[1, 5, 2],
[8, 3, 9]])
函数形式
max_func = np.max(arr13, axis=1)
print(f”函数形式 (np.max): {max_func}”)
方法形式
max_method = arr13.max(axis=1)
print(f”方法形式 (arr.max()): {max_method}”)
amax 别名
max_amax = np.amax(arr13, axis=1)
print(f”amax 别名 (np.amax): {max_amax}”)
尝试在方法中使用 initial 或 where (会报错)
try:
arr13.max(initial=0)
except TypeError as e:
print(f”\n尝试在方法中使用 initial 报错: {e}”)
try:
arr13.max(where=arr13 > 5)
except TypeError as e:
print(f”尝试在方法中使用 where 报错: {e}”)
“`
输出:
“`
函数形式 (np.max): [5 9]
方法形式 (arr.max()): [5 9]
amax 别名 (np.amax): [5 9]
尝试在方法中使用 initial 报错: max() got an unexpected keyword argument ‘initial’
尝试在方法中使用 where 报错: max() got an unexpected keyword argument ‘where’
“`
在大多数基本用例中,函数形式和方法形式可以互换使用。如果需要使用 initial
或 where
参数,或者喜欢将操作作为函数调用而非方法调用,则使用 np.max
或 np.amax
。
8. np.max
与 np.maximum
的区别
这是一个常见的混淆点。尽管名字相似,np.max
和 np.maximum
的功能完全不同。
np.max
(或np.amax
/array.max()
) 是一个归约操作 (reduction operation)。它沿着指定的轴查找最大值,将多个值归约(或压缩)为一个或一组最大值。np.maximum(x1, x2, /, out=None, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj])
是一个元素级操作 (element-wise operation)。它接收两个数组(或数组与标量),逐个比较对应位置的元素,并返回一个新数组,其中每个元素是输入数组对应位置元素中的较大值。
示例 8.1:np.max
vs np.maximum
“`python
import numpy as np
arr_a = np.array([1, 5, 2, 8])
arr_b = np.array([3, 2, 7, 4])
np.max: 查找数组内部的最大值
max_of_arr_a = np.max(arr_a)
print(f”np.max({arr_a}): {max_of_arr_a}”) # 查找 [1, 5, 2, 8] 中的最大值
np.maximum: 逐元素比较两个数组
element_wise_max = np.maximum(arr_a, arr_b)
print(f”np.maximum({arr_a}, {arr_b}): {element_wise_max}”)
比较 (1 vs 3) -> 3
比较 (5 vs 2) -> 5
比较 (2 vs 7) -> 7
比较 (8 vs 4) -> 8
结果是 [3, 5, 7, 8]
np.maximum 也可以用于数组与标量
element_wise_max_scalar = np.maximum(arr_a, 6)
print(f”np.maximum({arr_a}, 6): {element_wise_max_scalar}”)
比较 (1 vs 6) -> 6
比较 (5 vs 6) -> 6
比较 (2 vs 6) -> 6
比较 (8 vs 6) -> 8
结果是 [6, 6, 6, 8]
“`
输出:
np.max([1 5 2 8]): 8
np.maximum([1 5 2 8], [3 2 7 4]): [3 5 7 8]
np.maximum([1 5 2 8], 6): [6 6 6 8]
请务必区分这两种函数,它们的应用场景完全不同。np.max
用于查找数组中的峰值,而 np.maximum
用于合并两个数组或数组与标量,选择对应位置上的较大值。
9. 处理 NaN
值:np.nanmax
默认情况下,np.max
在遇到 NaN
(Not a Number)值时会遵循 IEEE 754 标准的行为:如果数组中包含任何 NaN
,那么无论其他元素有多大,结果都将是 NaN
。这通常不是我们期望的行为,很多时候我们希望计算忽略 NaN
值,只在非 NaN
的有效值中查找最大值。
NumPy 提供了 np.nanmax
函数来专门处理这种情况。np.nanmax
的用法与 np.max
非常相似,它会忽略输入数组中的所有 NaN
值,并在剩余的非 NaN
元素中查找最大值。
示例 9.1:np.max
vs np.nanmax
处理 NaN
“`python
import numpy as np
arr_with_nan = np.array([1, 5, np.nan, 8, 3, 9, np.nan, 4])
np.max 遇到 NaN 返回 NaN
max_with_nan_max = np.max(arr_with_nan)
print(f”包含 NaN 的数组: {arr_with_nan}”)
print(f”使用 np.max 查找最大值: {max_with_nan_max}”) # 结果是 NaN
np.nanmax 忽略 NaN
max_with_nan_nanmax = np.nanmax(arr_with_nan)
print(f”使用 np.nanmax 查找最大值: {max_with_nan_nanmax}”) # 忽略 NaN,在 [1, 5, 8, 3, 9, 4] 中找最大值
多维数组带 NaN
arr_2d_with_nan = np.array([[1, np.nan, 2],
[8, 3, 9],
[np.nan, 6, 7]])
print(f”\n包含 NaN 的二维数组:\n{arr_2d_with_nan}”)
np.max 按列 (axis=0)
max_2d_axis0_max = np.max(arr_2d_with_nan, axis=0)
print(f”使用 np.max 按列查找最大值 (axis=0):\n{max_2d_axis0_max}”)
第一列 [1, 8, nan],结果 nan
第二列 [nan, 3, 6],结果 nan
第三列 [2, 9, 7],结果 9
np.nanmax 按列 (axis=0)
max_2d_axis0_nanmax = np.nanmax(arr_2d_with_nan, axis=0)
print(f”使用 np.nanmax 按列查找最大值 (axis=0):\n{max_2d_axis0_nanmax}”)
第一列 [1, 8, nan],忽略 nan,在 [1, 8] 中找,结果 8
第二列 [nan, 3, 6],忽略 nan,在 [3, 6] 中找,结果 6
第三列 [2, 9, 7],忽略 nan,在 [2, 9, 7] 中找,结果 9
np.nanmax 按行 (axis=1)
max_2d_axis1_nanmax = np.nanmax(arr_2d_with_nan, axis=1)
print(f”使用 np.nanmax 按行查找最大值 (axis=1):\n{max_2d_axis1_nanmax}”)
第一行 [1, nan, 2],忽略 nan,在 [1, 2] 中找,结果 2
第二行 [8, 3, 9],忽略 nan,在 [8, 3, 9] 中找,结果 9
第三行 [nan, 6, 7],忽略 nan,在 [6, 7] 中找,结果 7
“`
输出:
“`
包含 NaN 的数组: [ 1. 5. nan 8. 3. 9. nan 4.]
使用 np.max 查找最大值: nan
使用 np.nanmax 查找最大值: 9.0
包含 NaN 的二维数组:
[[ 1. nan 2.]
[ 8. 3. 9.]
[nan 6. 7.]]
使用 np.max 按列查找最大值 (axis=0):
[nan nan 9.]
使用 np.nanmax 按列查找最大值 (axis=0):
[8. 6. 9.]
使用 np.nanmax 按行查找最大值 (axis=1):
[2. 9. 7.]
“`
如果使用 np.nanmax
的数组或指定维度上的所有元素都是 NaN
,np.nanmax
将返回该数据类型的“最小值”(对于浮点数是 -inf
)。
“`python
import numpy as np
arr_only_nan = np.array([np.nan, np.nan, np.nan])
max_only_nan = np.nanmax(arr_only_nan)
print(f”只有 NaN 的数组: {arr_only_nan}”)
print(f”使用 np.nanmax 查找最大值: {max_only_nan}”) # 结果是 -inf (对于浮点数)
arr_mix_nan_inf = np.array([np.nan, np.nan, -np.inf])
max_mix_nan_inf = np.nanmax(arr_mix_nan_inf)
print(f”只有 NaN 和 -inf 的数组: {arr_mix_nan_inf}”)
print(f”使用 np.nanmax 查找最大值: {max_mix_nan_inf}”) # 结果是 -inf
“`
输出:
只有 NaN 的数组: [nan nan nan]
使用 np.nanmax 查找最大值: -inf
只有 NaN 和 -inf 的数组: [nan nan -inf]
使用 np.nanmax 查找最大值: -inf
10. 常见应用场景
np.max
函数在各种数据处理和分析任务中都非常有用:
- 数据概览: 快速了解数据集或某个特征的最大值,帮助发现异常值或了解数据范围。
- 归一化: 在某些归一化技术中,可能需要找到数据的最大值。
- 图像处理: 在处理图像数据(通常表示为 NumPy 数组)时,可以用来找到图像中像素值的最大强度。
- 信号处理: 查找信号波形中的峰值。
- 机器学习: 在模型训练或评估中,可能需要计算输出结果的最大值,或者在某些层(如 Max Pooling 层)中使用最大值操作。
- 统计分析: 虽然 NumPy 本身不提供复杂的统计函数,但
max
是描述性统计中的一个基本量。
11. 性能考虑
NumPy 的核心是用 C 实现的,因此其数组操作(包括 np.max
)通常比纯 Python 循环要快得多,尤其是在处理大型数据集时。当对整个数组或整个轴进行操作时,NumPy 可以利用底层优化。使用 out
参数可以进一步减少内存开销,这在非常大的数组或高性能计算场景下可能很重要。
12. 总结
numpy.max
函数是 NumPy 库中用于查找数组(或其子维度)最大值的核心工具。通过灵活运用 axis
参数,可以在多维数组上实现按行、按列或按其他维度进行最大值归约。keepdims
参数在需要保留结果数组维度以方便广播时非常有用。initial
参数提供了处理空子集计算结果的方式。where
参数则允许基于条件对元素进行过滤后再进行最大值计算。
需要特别注意的是,np.max
是一个归约操作,与 np.maximum
这个元素级比较函数完全不同。此外,处理包含 NaN
值的数据时,应优先考虑使用 np.nanmax
来忽略 NaN
并计算有效元素的最大值。
熟练掌握 np.max
及其相关参数和函数,是高效进行 NumPy 数组操作和数据分析的基础。希望通过本文的详细解析和丰富示例,读者能够深入理解并灵活运用 numpy.max
。