NumPy max 详解与示例 – wiki基地


NumPy 之 max 函数详解与示例

NumPy 是 Python 中用于科学计算的核心库,提供了高性能的多维数组对象和用于处理这些数组的工具。在数据分析和科学计算中,查找数据集中的最大值是一项基本且常用的操作。NumPy 提供了 max 函数(以及其别名 amax 和数组方法 .max())来实现这一功能。

本文将详细介绍 NumPy 中 max 函数的各种用法,包括其基本功能、关键参数(如 axiskeepdimsoutinitialwhere)、与相关函数的区别(如 np.maximumnp.nanmax),并通过丰富的示例来帮助读者深入理解。

1. numpy.max 的基本概念

numpy.max(a, axis=None, out=None, keepdims=<no value>, initial=<no value>, where=<no value>)

这个函数的主要目的是找到一个数组(或数组中的指定维度)的最大值。

  • 输入 a: 这是一个必需的参数,表示需要进行最大值查找的输入数组(可以是 ndarray 或类似数组的对象,如 Python 列表、元组等)。
  • 返回值: 函数返回输入数组或指定维度上的最大值。返回值的形状取决于 axiskeepdims 参数。

最简单的用法是查找整个数组的最大值。

示例 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=0keepdims=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=Truemax_by_column 的形状是 (3,),与 arr6 (3, 3) 形状不兼容,直接相减会报错(或者需要额外的 reshape 操作)。

示例 3.2:axis=1keepdims=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 参数使用或者处理空数组时。

  • 如果数组为空,并且没有指定 initialnp.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:结合 whereinitial

结合 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.maxnp.amaxarray.max()

NumPy 提供了几种方式来执行最大值计算:

  • numpy.max(a, ...): 作为 NumPy 模块的函数。
  • numpy.amax(a, ...): 这是 numpy.max 的一个别名。在旧版本的 NumPy 或某些文档中可能会看到 amax,它们的功能是相同的。
  • array.max(axis=None, out=None, keepdims=False): 作为 ndarray 对象的方法。

区别:

  1. 调用方式: 函数形式 (np.maxnp.amax) 将数组作为第一个参数传入,而方法形式 (array.max()) 是直接在数组对象上调用的。
  2. 参数: 方法形式的 max 参数略少,它不支持 initialwhere 参数。
  3. keepdims 默认值: 函数形式 (np.max) 的 keepdims 默认值是一个特殊标记 <no value>,表示其行为会根据是否指定 axis 而定(如果指定 axis 则默认为 False,否则为 False 但行为类似 True 对于标量输出)。方法形式 (array.max()) 的 keepdims 默认值为 False。通常建议显式指定 keepdims=TrueFalse 以避免混淆。

示例 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’
“`

在大多数基本用例中,函数形式和方法形式可以互换使用。如果需要使用 initialwhere 参数,或者喜欢将操作作为函数调用而非方法调用,则使用 np.maxnp.amax

8. np.maxnp.maximum 的区别

这是一个常见的混淆点。尽管名字相似,np.maxnp.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 的数组或指定维度上的所有元素都是 NaNnp.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


发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部