NumPy 1.26 中文文档(四十三)

2024-06-28 16:20:44 浏览数 (2)

原文:numpy.org/doc/

numpy.histogramdd

原文:numpy.org/doc/1.26/reference/generated/numpy.histogramdd.html

代码语言:javascript复制
numpy.histogramdd(sample, bins=10, range=None, density=None, weights=None)

计算一些数据的多维直方图。

参数:

sample(N,D)数组,或(N,D)array_like

要制作直方图的数据。

注意当 array_like 时,样本的不寻常解释:

  • 当数组时,每行是 D 维空间中的一个坐标,例如histogramdd(np.array([p1, p2, p3]))
  • 当 array_like 时,每个元素是单个坐标的值列表,例如 histogramdd((X, Y, Z))

应优先使用第一种形式。

bins序列或 int,可选

箱子规格:

  • 一系列描述沿每个维度单调增加的箱边的数组。
  • 每个维度的箱数(nx,ny,… = bins)
  • 所有维度的箱数(nx=ny=…= bins)。

range序列,可选

长度为 D 的序列,每个序列都是一个可选的(lower,upper)元组,给出如果边界没有在bins中显式地给出时要使用的外部箱边缘。序列中的 None 条目导致相应维度的最小值和最大值被用于。默认值 None 相当于传递了 D 个 None 值的元组。

density布尔值,可选

如果为 False,返回每个箱中的样本数。如果为 True,则返回在箱中的概率密度函数,bin_count / sample_count / bin_volume

weights(N,)array_like,可选

一系列值w_i,用于加权每个样本*(x_i, y_i, z_i, …)*。如果密度为 True,则权重被标准化为 1。如果密度为 False,则返回的直方图的值等于属于落入每个箱中的样本的权重之和。

返回:

H ndarray

样本 x 的多维直方图。请参阅密度和权重以了解不同的可能语义。

edges列表

由 D 个数组描述每个维度的箱边的列表。

另请参阅

histogram

1-D 直方图

histogram2d

2-D 直方图

示例

代码语言:javascript复制
>>> r = np.random.randn(100,3)
>>> H, edges = np.histogramdd(r, bins = (5, 8, 4))
>>> H.shape, edges[0].size, edges[1].size, edges[2].size
((5, 8, 4), 6, 9, 5) 

numpy.bincount

原文:numpy.org/doc/1.26/reference/generated/numpy.bincount.html

代码语言:javascript复制
numpy.bincount(x, /, weights=None, minlength=0)

统计非负整数数组中每个值的出现次数。

bins 的数量(大小为 1)比x中的最大值大 1。如果指定了minlength,输出数组中至少会有这么多个 bins(如果有必要,根据x的内容,它可能会更长)。每个 bin 给出x中其索引值出现的次数。如果指定了weights,输入数组将被它加权,即如果在位置i找到值n,则out[n] = weight[i],而不是out[n] = 1

参数:

xarray_like,1 维,非负整数

输入数组。

weightsarray_like,可选

权重,与x的形状相同的数组。

minlengthint,可选

输出数组的最小数量的 bin。

版本 1.6.0 中的新内容。

返回结果:

out一维整数数组

将输入数组进行分箱的结果。out的长度等于np.amax(x) 1

引发:

ValueError

如果输入不是一维的,或者包含负值的元素,或者minlength为负。

TypeError

如果输入的类型为浮点数或复数。

另请参见

histogram, digitize, unique

示例

代码语言:javascript复制
>>> np.bincount(np.arange(5))
array([1, 1, 1, 1, 1])
>>> np.bincount(np.array([0, 1, 1, 3, 2, 1, 7]))
array([1, 3, 1, 1, 0, 0, 0, 1]) 
代码语言:javascript复制
>>> x = np.array([0, 1, 1, 3, 2, 1, 7, 23])
>>> np.bincount(x).size == np.amax(x) 1
True 

输入数组需要为整数类型,否则会引发 TypeError:

代码语言:javascript复制
>>> np.bincount(np.arange(5, dtype=float))
Traceback (most recent call last):
  ...
TypeError: Cannot cast array data from dtype('float64') to dtype('int64')
according to the rule 'safe' 

bincount的一种可能用途是使用weights关键字对数组的可变大小块进行求和。

代码语言:javascript复制
>>> w = np.array([0.3, 0.5, 0.2, 0.7, 1., -0.6]) # weights
>>> x = np.array([0, 1, 1, 2, 2, 2])
>>> np.bincount(x,  weights=w)
array([ 0.3,  0.7,  1.1]) 

numpy.histogram_bin_edges

原文:numpy.org/doc/1.26/reference/generated/numpy.histogram_bin_edges.html

代码语言:javascript复制
numpy.histogram_bin_edges(a, bins=10, range=None, weights=None)

用于计算histogram函数使用的箱边缘的函数。

参数:

aarray_like

输入数据。直方图是在平坦的数组上计算的。

binsint 或标量序列或 str, 可选

如果bins是一个整数,则它定义了给定范围内等宽箱的数量(默认为 10)。如果bins是一个序列,则它定义了箱边缘,包括右边的边缘,允许非均匀的箱宽。

如果bins是下面列表中的字符串之一, histogram_bin_edges将利用所选的方法来计算最佳箱宽,从而计算出难以掉落在所要求范围内的数据的箱的数量(有关估计器的更多细节,请参见注释)。虽然箱宽对范围内的实际数据最佳,但箱数量将被计算,以填满整个范围,包括空的部分。对于可视化,建议使用‘auto’选项。不支持自动箱大小选择的加权数据。

‘auto’

‘sturges’和‘fd’估计器的最大值。提供全面的优越性能。

‘fd’(Freedman Diaconis 估计器)

鲁棒(对异常值具有韧性)的估计器,需要考虑数据的变化性和数据规模。

‘doane’

与 Sturges’估计器的改进版本,更适用于非正态数据集。

‘scott’

考虑数据变异性和数据规模的相对不那么鲁棒的估计器。

‘stone’

基于留一法交叉验证估计积分平方误差。可以看作是 Scott’s 法规的一般化。

‘rice’

估计器不考虑变异性,只考虑数据大小。通常高估所需的箱的数量。

‘sturges’

R 的默认方法,只考虑数据规模。仅适用于高斯数据,并且低估大型非高斯数据集的箱的数量。

‘sqrt’

数据规模的平方根估计器,由 Excel 和其他程序使用,因其速度和简单性。

浮点数, 浮点数), 可选

箱的上限范围。如果未提供,范围简单地是(a.min(), a.max())。超出范围的值将被忽略。范围的第一个元素必须小于或等于第二个元素。range也会影响自动箱计算。虽然基于range内实际数据计算出最佳的箱宽,但箱数量将填满整个范围,包括不含数据的部分。

weightsarray_like, 可选

a形状相同的权重数组。a中的每个值只对箱计数贡献其关联的权重(而不是 1)。目前还没有任何箱估计器使用这个,但将来可能会使用。

返回:

bin_edges浮点数 dtype 的数组

histogram 传入的边缘

另请参阅

histogram

注意

通过文献提供的方法来估计最佳柱数,这些方法受到了 R 提供直方图可视化的启发。注意,将柱的数量与 (n^{1/3}) 成比例是渐近最优的,这也是大多数估计器中出现的原因。这些只是提供柱数量的良好起点的插入方法。在下面的方程中,(h) 是柱宽,(n_h) 是柱数量。所有计算柱计数的估计器都使用数据的 ptp 重新调整为柱宽度。最终的柱计数是通过 np.round(np.ceil(range / h)) 得到的。最终的柱宽度通常小于下面估计器返回的值。

‘auto’(‘sturges’ 和 ‘fd’ 估计器的最大值)

通过不同估计器之间的权衡得到一个良好的值。对于小数据集,通常选择 Sturges 值,而对于大数据集,通常默认为 FD。避免了 FD 和 Sturges 对小和大数据集的过于保守行为。切换点通常是 (a.size approx 1000)。

‘fd’(Freedman-Diaconis 估计器)

[h = 2 frac{IQR}{n^{1/3}}]

The binwidth is proportional to the interquartile range (IQR) and inversely proportional to cube root of a.size. Can be too conservative for small datasets, but is quite good for large datasets. The IQR is very robust to outliers.

‘scott’

[h = sigma sqrt[3]{frac{24 sqrt{pi}}{n}}]

The binwidth is proportional to the standard deviation of the data and inversely proportional to cube root of x.size. Can be too conservative for small datasets, but is quite good for large datasets. The standard deviation is not very robust to outliers. Values are very similar to the Freedman-Diaconis estimator in the absence of outliers.

‘rice’

[n_h = 2n^{1/3}]

柱的数量仅与 a.size 的立方根成比例。它往往会高估柱的数量,而且它不考虑数据的变异性。

‘sturges’

[n_h = log _{2}(n) 1]

柱的数量是 a.size 的以 2 为底的对数。该估计器假设数据呈正态分布,对于较大、非正态的数据过于保守。这是 R 中 hist 方法的默认方法。

‘doane’

[ begin{align}begin{aligned}n_h = 1 log_{2}(n) log_{2}left(1 frac{|g_1|}{sigma_{g_1}}right)g_1 = meanleft[left(frac{x - mu}{sigma}right)³right]\sigma_{g_1} = sqrt{frac{6(n - 2)}{(n 1)(n 3)}}end{aligned}end{align} ]

对非正态数据产生更好的估计的 Sturges 公式的改进版本。该估计器试图解释数据的偏斜。

‘sqrt’

[n_h = sqrt n]

最简单和最快速的估计器。只考虑数据的大小。

示例

代码语言:javascript复制
>>> arr = np.array([0, 0, 0, 1, 2, 3, 3, 4, 5])
>>> np.histogram_bin_edges(arr, bins='auto', range=(0, 1))
array([0.  , 0.25, 0.5 , 0.75, 1.  ])
>>> np.histogram_bin_edges(arr, bins=2)
array([0. , 2.5, 5. ]) 

为了与直方图保持一致,一个预先计算的箱子数组被不经修改地传递:

代码语言:javascript复制
>>> np.histogram_bin_edges(arr, [1, 2])
array([1, 2]) 

这个函数允许计算一组箱子,并在多个直方图中重复使用:

代码语言:javascript复制
>>> shared_bins = np.histogram_bin_edges(arr, bins='auto')
>>> shared_bins
array([0., 1., 2., 3., 4., 5.]) 
代码语言:javascript复制
>>> group_id = np.array([0, 1, 1, 0, 1, 1, 0, 1, 1])
>>> hist_0, _ = np.histogram(arr[group_id == 0], bins=shared_bins)
>>> hist_1, _ = np.histogram(arr[group_id == 1], bins=shared_bins) 
代码语言:javascript复制
>>> hist_0; hist_1
array([1, 1, 0, 1, 0])
array([2, 0, 1, 1, 2]) 

哪种方法提供的结果更容易比较,而不是为每个直方图使用单独的箱子:

代码语言:javascript复制
>>> hist_0, bins_0 = np.histogram(arr[group_id == 0], bins='auto')
>>> hist_1, bins_1 = np.histogram(arr[group_id == 1], bins='auto')
>>> hist_0; hist_1
array([1, 1, 1])
array([2, 1, 1, 2])
>>> bins_0; bins_1
array([0., 1., 2., 3.])
array([0.  , 1.25, 2.5 , 3.75, 5.  ]) 

numpy.digitize

原文:numpy.org/doc/1.26/reference/generated/numpy.digitize.html

代码语言:javascript复制
numpy.digitize(x, bins, right=False)

返回输入数组中每个值所属的区间的索引。

right

区间顺序

返回的索引 i 满足

False

递增

bins[i-1] <= x < bins[i]

True

递增

bins[i-1] < x <= bins[i]

False

递减

bins[i-1] > x >= bins[i]

True

递减

bins[i-1] >= x > bins[i]

如果x中的值超出bins的范围,则适当返回 0 或len(bins)

参数:

xarray_like

要进行分箱的输入数组。在 NumPy 1.10.0 之前,此数组必须是一维的,但现在可以具有任何形状。

binsarray_like

区间数组。必须是一维且单调递增的。

rightbool,可选

指示区间是否包括右边缘或左边缘。默认行为是(right==False),表示区间不包括右边缘。在这种情况下,左边缘是开放的,即,对于单调递增的区间,bins[i-1] <= x < bins[i] 是默认行为。

返回:

indices整数的 ndarray

x相同形状的索引输出数组。

引发:

值错误

如果 bins 不是单调的。

类型错误

如果输入的类型是复数。

另请参阅

bincount, histogram, unique, searchsorted

注意事项

如果x中的值使其超出区间范围,则尝试使用digitize 返回的索引索引bins将导致 IndexError。

新版本 1.10.0 中新增。

np.digitize 是基于 np.searchsorted 实现的。这意味着使用二分搜索对值进行分箱,对于更大数量的区间,比以前的线性搜索更具规模优势。它还消除了输入数组必须是一维的要求。

对于单调 _ 递增 _ 的 bins,以下是等效的:

代码语言:javascript复制
np.digitize(x, bins, right=True)
np.searchsorted(bins, x, side='left') 

请注意,由于参数的顺序已颠倒,因此侧边也必须如此。searchsorted 调用稍微更快,因为它不执行任何单调性检查。或许更重要的是,它支持所有的数据类型。

示例

代码语言:javascript复制
>>> x = np.array([0.2, 6.4, 3.0, 1.6])
>>> bins = np.array([0.0, 1.0, 2.5, 4.0, 10.0])
>>> inds = np.digitize(x, bins)
>>> inds
array([1, 4, 3, 2])
>>> for n in range(x.size):
...   print(bins[inds[n]-1], "<=", x[n], "<", bins[inds[n]])
...
0.0 <= 0.2 < 1.0
4.0 <= 6.4 < 10.0
2.5 <= 3.0 < 4.0
1.0 <= 1.6 < 2.5 
代码语言:javascript复制
>>> x = np.array([1.2, 10.0, 12.4, 15.5, 20.])
>>> bins = np.array([0, 5, 10, 15, 20])
>>> np.digitize(x,bins,right=True)
array([1, 2, 3, 4, 4])
>>> np.digitize(x,bins,right=False)
array([1, 3, 3, 4, 5]) 

测试支持(numpy.testing

原文:numpy.org/doc/1.26/reference/routines.testing.html

所有 numpy 测试脚本的通用测试支持。

这个单一模块应该在一个位置提供所有 numpy 测试的通用功能,因此 test scripts 可以直接导入它并立即运行。更多背景信息,请参阅测试指南

断言

assert_allclose(actual, desired[, rtol, …])

如果两个对象不等到期望的公差,将引发 AssertionError。

assert_array_almost_equal_nulp(x, y[, nulp])

相对于它们的间距比较两个数组。

assert_array_max_ulp(a, b[, maxulp, dtype])

检查所有数组项在最后位置上的单位最多相差 N 个单位。

assert_array_equal(x, y[, err_msg, verbose, …])

如果两个 array_like 对象不相等,则引发 AssertionError。

assert_array_less(x, y[, err_msg, verbose])

如果两个 array_like 对象不按顺序排列,则引发 AssertionError。

assert_equal(actual, desired[, err_msg, verbose])

如果两个对象不等,则引发 AssertionError。

assert_raises(assert_raises)

除非在使用参数 args 和关键字参数 kwargs 调用可调用函数时抛出 exception_class 类的异常,否则将失败。

assert_raises_regex(exception_class, …)

除非在使用参数 args 和关键字参数 kwargs 调用可调用函数时抛出类为 exception_class 并且带有匹配预期正则表达式的消息的异常,否则将失败。

assert_warns(warning_class, *args, **kwargs)

除非给定的可调用函数引发指定的警告,否则将失败。

assert_no_warnings(*args, **kwargs)

如果给定的可调用对象产生任何警告,则失败。

assert_no_gc_cycles(*args, **kwargs)

如果给定的可调用对象产生任何引用循环,则失败。

assert_string_equal(actual, desired)

测试两个字符串是否相等。

断言(不建议使用)

建议使用 assert_allcloseassert_array_almost_equal_nulpassert_array_max_ulp 替代这些函数,以进行更一致的浮点数比较。

assert_(val[, msg])

在发布模式下运行的断言。

assert_almost_equal(actual, desired[, …])

如果两个项目在所需精度上不相等,则引发 AssertionError。

assert_approx_equal(actual, desired[, …])

如果两个项目在有效数字上不相等,则引发 AssertionError。

assert_array_almost_equal(x, y[, decimal, …])

如果两个对象在所需精度上不相等,则引发 AssertionError。

print_assert_equal(test_string, actual, desired)

测试两个对象是否相等,如果测试失败则打印错误消息。

装饰器

decorate_methods(cls, decorator[, testmatch])

将装饰器应用于类中所有与正则表达式匹配的方法。

测试运行

clear_and_catch_warnings([record, modules])

重置警告注册表以捕获警告的上下文管理器。

measure(code_str[, times, label])

返回在调用者命名空间中执行代码的经过时间。

rundocs([filename, raise_on_error])

运行给定文件中的 doctests。

suppress_warnings([forwarding_rule])

上下文管理器和装饰器的作用与warnings.catch_warnings相似。

指南

  • 测试指南
    • 介绍
    • 测试 NumPy
      • 从 Python 内部运行测试
      • 从命令行运行测试
      • 运行测试的其他方法
    • 编写自己的测试
      • 在测试中使用 C 代码
        • build_and_import_extension
      • 测试标记
      • 更简单的设置和拆卸函数/方法
      • 参数化测试
      • Doctests(文档测试)
      • tests/
      • __init__.pysetup.py
    • 技巧和窍门
      • 创建许多相似的测试
      • 已知失败和跳过测试
      • 对随机数据进行测试
      • numpy.test的文档
        • test

断言

assert_allclose(actual, desired[, rtol, …])

如果两个对象在期望的容差范围内不相等,则引发 AssertionError。

assert_array_almost_equal_nulp(x, y[, nulp])

相对于它们的间距比较两个数组。

assert_array_max_ulp(a, b[, maxulp, dtype])

检查数组的所有元素在最后一位单位内的差异最多为 N 个单位。

assert_array_equal(x, y[, err_msg, verbose, …])

如果两个类似数组对象不相等,则引发 AssertionError。

assert_array_less(x, y[, err_msg, verbose])

如果两个类似数组对象的顺序不是按照小于来排列,则引发 AssertionError。

assert_equal(actual, desired[, err_msg, verbose])

如果两个对象不相等,则引发 AssertionError。

assert_raises(assert_raises)

除非在调用参数为 args 和关键字参数为 kwargs 的可调用函数时抛出 exception_class 类的异常,则不通过。

assert_raises_regex(exception_class, …)

除非在调用参数为 args 和关键字参数为 kwargs 的可调用函数时抛出的消息与预期的正则表达式匹配的类为 exception_class 的异常,则不通过。

assert_warns(warning_class, *args, **kwargs)

除非给定的可调用函数引发指定的警告,否则不通过。

assert_no_warnings(*args, **kwargs)

如果给定的可调用函数产生任何警告,则不通过。

assert_no_gc_cycles(*args, **kwargs)

如果给定的可调用函数产生任何引用循环,则不通过。

assert_string_equal(actual, desired)

测试两个字符串是否相等。

断言(不推荐使用)

建议使用 assert_allcloseassert_array_almost_equal_nulpassert_array_max_ulp 中的一个,而不是使用这些函数进行更一致的浮点数比较。

assert_(val[, msg])

在发布模式下工作的断言。

assert_almost_equal(actual, desired[, …])

如果两个项目不在期望的精度范围内相等,则引发 AssertionError。

assert_approx_equal(actual, desired[, …])

如果两个项目不符合预期的有效位数,则引发 AssertionError。

assert_array_almost_equal(x, y[, decimal, …])

如果两个对象不符合期望精度,则引发 AssertionError。

print_assert_equal(test_string, actual, desired)

测试两个对象是否相等,如果测试失败则打印错误信息。

装饰器

decorate_methods(cls, decorator[, testmatch])

对类中匹配正则表达式的所有方法应用装饰器。

测试运行

clear_and_catch_warnings([record, modules])

上下文管理器,用于捕获警告的情况下重置警告注册表

measure(code_str[, times, label])

返回在调用者命名空间中执行代码的经过时间。

rundocs([filename, raise_on_error])

运行给定文件中的 doctests。

suppress_warnings([forwarding_rule])

上下文管理器和装饰器,做了类似于 warnings.catch_warnings 的事情。

指南

  • 测试指南
    • 介绍
    • 测试 NumPy
      • 从 Python 中运行测试
      • 从命令行运行测试
      • 运行测试的其他方法
    • 编写自己的测试
      • 在测试中使用 C 代码
        • build_and_import_extension
      • 为测试打标签
      • 更容易的设置和拆卸功能/方法
      • 参数化测试
      • Doctests
      • tests/
      • __init__.pysetup.py
    • 技巧
      • 创建许多相似的测试
      • 已知失败 & 跳过测试
      • 随机数据上的测试
      • numpy.test的文档
        • test

numpy.testing.assert_allclose

原文:numpy.org/doc/1.26/reference/generated/numpy.testing.assert_allclose.html

代码语言:javascript复制
testing.assert_allclose(actual, desired, rtol=1e-07, atol=0, equal_nan=True, err_msg='', verbose=True)

如果两个对象不相等,就会引发 AssertionError。

给定两个类数组对象,检查它们的形状和所有元素是否相等(但参见标量的特殊处理)。如果形状不匹配或任何值冲突,则会引发异常。与 numpy 中的标准用法不同,NaN 会像数字一样进行比较,如果两个对象在相同位置都有 NaN,则不会引发断言。

该测试相当于allclose(actual, desired, rtol, atol)(注意allclose具有不同的默认值)。它比较actualdesired的差异与atol rtol * abs(desired)

版本 1.5.0 中的新内容。

参数:

actual类数组

获得的数组。

desired类数组

期望的数组。

rtol浮点数,可选

相对容差。

atol浮点数,可选

绝对容差。

equal_nan布尔值,可选。

如果为 True,NaN 会比较相等。

err_msg字符串,可选

失败时打印的错误消息。

verbose布尔值,可选

如果为 True,冲突的值将附加到错误消息中。

引发:

断言错误

如果实际值和期望值在指定精度上不相等。

参见

assert_array_almost_equal_nulpassert_array_max_ulp

注意

actualdesired之一是标量而另一个是类数组时,函数会检查类数组对象的每个元素是否等于标量。

示例

代码语言:javascript复制
>>> x = [1e-5, 1e-3, 1e-1]
>>> y = np.arccos(np.cos(x))
>>> np.testing.assert_allclose(x, y, rtol=1e-5, atol=0) 

numpy.testing.assert_array_almost_equal_nulp

原文:numpy.org/doc/1.26/reference/generated/numpy.testing.assert_array_almost_equal_nulp.html

代码语言:javascript复制
testing.assert_array_almost_equal_nulp(x, y, nulp=1)

相对于它们的间距比较两个数组。

这是一种相对稳健的方法,可比较幅度变化的两个数组。

参数:

x, yarray_like

输入数组。

nulpint,可选

公差的最大最后一位单位数(请参见注意事项)。默认值为 1。

返回:

引发:

AssertionError

如果一个或多个元素的xy之间的间距大于nulp

参见

assert_array_max_ulp

检查数组的所有项是否在最后一位最多相差 N 个单位。

spacing

返回x和最近的相邻数字之间的距离。

注意事项

如果不符合以下条件,则会引发断言:

代码语言:javascript复制
abs(x - y) <= nulp * spacing(maximum(abs(x), abs(y))) 

举例

代码语言:javascript复制
>>> x = np.array([1., 1e-10, 1e-20])
>>> eps = np.finfo(x.dtype).eps
>>> np.testing.assert_array_almost_equal_nulp(x, x*eps/2   x) 
代码语言:javascript复制
>>> np.testing.assert_array_almost_equal_nulp(x, x*eps   x)
Traceback (most recent call last):
  ...
AssertionError: X and Y are not equal to 1 ULP (max is 2) 

numpy.testing.assert_array_max_ulp

原文:numpy.org/doc/1.26/reference/generated/numpy.testing.assert_array_max_ulp.html

代码语言:javascript复制
testing.assert_array_max_ulp(a, b, maxulp=1, dtype=None)

检查数组中所有项目的最后一位的单位之间的差异是否至多为 N 个。

参数:

a, barray_like

要比较的输入数组。

maxulpint,可选

ab元素之间可以有的最大单位数。默认值为 1。

dtypedtype,可选

如果提供,则转换ab的数据类型。默认值为 None。

返回:

retndarray

包含ab之间可表示的浮点数的数组。

引发:

断言错误

如果一个或多个元素的差异超过maxulp

另请参阅

assert_array_almost_equal_nulp

相对于它们的间距比较两个数组。

注意

用于计算 ULP 差异,此 API 不区分 NAN 的各种表示形式(0x7fc00000 和 0xffc00000 之间的 ULP 差异为零)。

示例

代码语言:javascript复制
>>> a = np.linspace(0., 1., 100)
>>> res = np.testing.assert_array_max_ulp(a, np.arcsin(np.sin(a))) 

numpy.testing.assert_array_equal

原文:numpy.org/doc/1.26/reference/generated/numpy.testing.assert_array_equal.html

代码语言:javascript复制
testing.assert_array_equal(x, y, err_msg='', verbose=True, *, strict=False)

如果两个类似数组对象不相等,则引发 AssertionError。

给定两个类似数组的对象,检查形状是否相等,并且这些对象的所有元素是否相等(但请参见标量的特殊处理的注释部分)。如果形状不匹配或值冲突,将引发异常。与 numpy 中的标准用法相反,NaN 将被视为数字进行比较,如果两个对象在相同位置具有 NaN,则不会引发断言。

建议使用浮点数验证相等性时应保持常规谨慎。

参数:

xarray_like

要检查的实际对象。

yarray_like

所需的,期望的对象。

err_msgstr,可选

在比较标量与数组时引发 AssertionError 的错误消息。

verbosebool,可选

如果为 True,则冲突的值将追加到错误消息中。

strictbool,可选

如果为 True,则在数组对象的形状或数据类型不匹配时引发 AssertionError。禁用了在注释部分提到的标量的特殊处理。

版本 1.24.0 中的新功能。

引发:

AssertionError

如果实际对象和期望对象不相等。

另请参阅

assert_allclose

使用所需的相对和/或绝对精度比较两个类似数组的对象是否相等。

assert_array_almost_equal_nulpassert_array_max_ulpassert_equal

注释

xy 中的一个是标量,另一个是类似数组时,函数将检查类似数组对象的每个元素是否等于标量。可以使用 strict 参数禁用此行为。

示例

第一个断言不会引发异常:

代码语言:javascript复制
>>> np.testing.assert_array_equal([1.0,2.33333,np.nan],
...                               [np.exp(0),2.33333, np.nan]) 

对于浮点数存在数值不精确的断言失败:

代码语言:javascript复制
>>> np.testing.assert_array_equal([1.0,np.pi,np.nan],
...                               [1, np.sqrt(np.pi)**2, np.nan])
Traceback (most recent call last):
  ...
AssertionError:
Arrays are not equal

Mismatched elements: 1 / 3 (33.3%)
Max absolute difference: 4.4408921e-16
Max relative difference: 1.41357986e-16
 x: array([1.      , 3.141593,      nan])
 y: array([1.      , 3.141593,      nan]) 

对于这些情况,请使用 assert_allclose 或 nulp(浮点数值的数量)函数之一:

代码语言:javascript复制
>>> np.testing.assert_allclose([1.0,np.pi,np.nan],
...                            [1, np.sqrt(np.pi)**2, np.nan],
...                            rtol=1e-10, atol=0) 

正如在注释部分中提到的,assert_array_equal 对标量具有特殊处理。此处的测试检查 x 中的每个值是否为 3:

代码语言:javascript复制
>>> x = np.full((2, 5), fill_value=3)
>>> np.testing.assert_array_equal(x, 3) 

使用 strict 来确保数组数据类型匹配:

代码语言:javascript复制
>>> np.testing.assert_array_equal(x, 3, strict=True)
Traceback (most recent call last):
  ...
AssertionError:
Arrays are not equal

(shapes (2, 5), () mismatch)
 x: array([[3, 3, 3, 3, 3],
 [3, 3, 3, 3, 3]])
 y: array(3) 

strict 参数还确保数组数据类型匹配:

代码语言:javascript复制
>>> x = np.array([2, 2, 2])
>>> y = np.array([2., 2., 2.], dtype=np.float32)
>>> np.testing.assert_array_equal(x, y, strict=True)
Traceback (most recent call last):
  ...
AssertionError:
Arrays are not equal

(dtypes int64, float32 mismatch)
 x: array([2, 2, 2])
 y: array([2., 2., 2.], dtype=float32) 

numpy.testing.assert_array_less

原文:numpy.org/doc/1.26/reference/generated/numpy.testing.assert_array_less.html

代码语言:javascript复制
testing.assert_array_less(x, y, err_msg='', verbose=True)

如果两个类似数组对象不按小于进行排序,则引发 AssertionError。

给定两个类似数组对象,检查形状是否相等,以及第一个对象的所有元素是否严格小于第二个对象的元素。在形状不匹配或值错误排序时引发异常。如果对象的维度为零,则形状不匹配不会引发异常。与 numpy 中的标准用法相反,NaNs 会被比较,如果两个对象在相同位置具有 NaNs,则不会引发断言。

参数:

x 类似数组对象

要检查的较小对象。

y 类似数组对象

要比较的较大对象。

err_msg 字符串

在失败情况下打印的错误消息。

verbose 布尔类型

如果为 True,则将冲突的值附加到错误消息中。

引发:

AssertionError

如果 x 在元素级别上不严格小于 y。

另请参见

assert_array_equal

测试对象是否相等

assert_array_almost_equal

测试对象是否相等,精度高达

示例

代码语言:javascript复制
>>> np.testing.assert_array_less([1.0, 1.0, np.nan], [1.1, 2.0, np.nan])
>>> np.testing.assert_array_less([1.0, 1.0, np.nan], [1, 2.0, np.nan])
Traceback (most recent call last):
  ...
AssertionError:
Arrays are not less-ordered

Mismatched elements: 1 / 3 (33.3%)
Max absolute difference: 1.
Max relative difference: 0.5
 x: array([ 1.,  1., nan])
 y: array([ 1.,  2., nan]) 
代码语言:javascript复制
>>> np.testing.assert_array_less([1.0, 4.0], 3)
Traceback (most recent call last):
  ...
AssertionError:
Arrays are not less-ordered

Mismatched elements: 1 / 2 (50%)
Max absolute difference: 2.
Max relative difference: 0.66666667
 x: array([1., 4.])
 y: array(3) 
代码语言:javascript复制
>>> np.testing.assert_array_less([1.0, 2.0, 3.0], [4])
Traceback (most recent call last):
  ...
AssertionError:
Arrays are not less-ordered

(shapes (3,), (1,) mismatch)
 x: array([1., 2., 3.])
 y: array([4]) 

numpy.testing.assert_equal

原文:numpy.org/doc/1.26/reference/generated/numpy.testing.assert_equal.html

代码语言:javascript复制
testing.assert_equal(actual, desired, err_msg='', verbose=True)

如果两个对象不相等,则引发断言错误。

给定两个对象(标量、列表、元组、字典或 numpy 数组),检查这些对象的所有元素是否相等。在出现第一个冲突值时引发异常。

actualdesired中的一个是标量,另一个是类似数组时,该函数会检查数组对象的每个元素是否等于标量。

该函数将处理 NaN 的比较,就好像 NaN 是一个“正常”的数字一样。也就是说,如果两个对象在相同位置都有 NaN,那么不会引发断言错误。这与 IEEE 关于 NaN 的标准相反,该标准规定 NaN 与任何东西的比较都必须返回 False。

参数:

actual 类似数组

要检查的对象。

desired 类似数组

期望的对象。

err_msg str,可选

在发生失败时要打印的错误消息。

verbose 布尔,可选

如果为 True,则冲突的值将添加到错误消息中。

引发:

断言错误

如果 actual 和 desired 不相等。

示例

代码语言:javascript复制
>>> np.testing.assert_equal([4,5], [4,6])
Traceback (most recent call last):
  ...
AssertionError:
Items are not equal:
item=1
 ACTUAL: 5
 DESIRED: 6 

以下比较不会引发异常。输入中存在 NaN,但它们位于相同位置。

代码语言:javascript复制
>>> np.testing.assert_equal(np.array([1.0, 2.0, np.nan]), [1, 2, np.nan]) 

numpy.testing.assert_raises

原文:numpy.org/doc/1.26/reference/generated/numpy.testing.assert_raises.html

代码语言:javascript复制
testing.assert_raises(exception_class, callable, *args, **kwargs) assert_raises(exception_class)
代码语言:javascript复制
testing.assert_raises(exception_class) → None

当使用参数 args 和关键字参数 kwargs 调用可调用对象时,如果抛出了 exception_class 类的异常,则失败。如果抛出了不同类型的异常,它不会被捕获,测试用例将被视为发生错误,就像发生了意外异常一样。

或者,assert_raises可以作为上下文管理器使用:

代码语言:javascript复制
>>> from numpy.testing import assert_raises
>>> with assert_raises(ZeroDivisionError):
...     1 / 0 

等价于

代码语言:javascript复制
>>> def div(x, y):
...     return x / y
>>> assert_raises(ZeroDivisionError, div, 1, 0) 

numpy.testing.assert_raises_regex

原文:numpy.org/doc/1.26/reference/generated/numpy.testing.assert_raises_regex.html

代码语言:javascript复制
testing.assert_raises_regex(exception_class, expected_regexp, callable, *args, **kwargs) assert_raises_regex(exception_class, expected_regexp)

调用时使用参数 args 和关键字参数 kwargs 调用时,除非 callable 抛出与 expected_regexp 匹配的消息的 exception_class 类的异常,否则失败。

也可以像assert_raises一样作为上下文管理器使用。

备注

自 1.9.0 版本开始新增。

numpy.testing.assert_warns

原文:numpy.org/doc/1.26/reference/generated/numpy.testing.assert_warns.html

代码语言:javascript复制
testing.assert_warns(warning_class, *args, **kwargs)

除非给定的可调用对象引发指定的警告,否则将失败。

当使用参数 args 和关键字参数 kwargs 调用时,应由可调用对象抛出 warning_class 类型的警告。如果抛出了不同类型的警告,则不会捕获。

如果调用时省略了除警告类之外的所有参数,则可用作上下文管理器:

使用 assert_warns(SomeWarning): do_something()

能够用作上下文管理器是 NumPy v1.11.0 中的新功能。

版本 1.4.0 中的新功能。

参数:

warning_class

定义了 func 预期抛出的警告的类。

func可调用对象,可选

可调用对象进行测试

*args参数

func 的参数。

****kwargs**关键字参数

func 的关键字参数。

返回:

func 返回的值。

示例

代码语言:javascript复制
>>> import warnings
>>> def deprecated_func(num):
...     warnings.warn("Please upgrade", DeprecationWarning)
...     return num*num
>>> with np.testing.assert_warns(DeprecationWarning):
...     assert deprecated_func(4) == 16
>>> # or passing a func
>>> ret = np.testing.assert_warns(DeprecationWarning, deprecated_func, 4)
>>> assert ret == 16 

numpy.testing.assert_no_warnings

原文:numpy.org/doc/1.26/reference/generated/numpy.testing.assert_no_warnings.html

代码语言:javascript复制
testing.assert_no_warnings(*args, **kwargs)

如果给定的可调用对象产生任何警告,则失败。

如果所有参数被省略调用,则可用作上下文管理器:

使用 assert_no_warnings(): do_something()

在 NumPy v1.11.0 中新增了作为上下文管理器使用的功能。

新版本 1.7.0 中新增功能。

参数:

funccallable

要测试的可调用对象。

*args参数

传递给 func 的参数。

****kwargs**关键字参数

传递给 func 的关键字参数。

返回:

func 返回的值。

numpy.testing.assert_no_gc_cycles

numpy.org/doc/1.26/reference/generated/numpy.testing.assert_no_gc_cycles.html

代码语言:javascript复制
testing.assert_no_gc_cycles(*args, **kwargs)

如果给定的可调用函数产生任何引用循环,则失败。

如果所有参数都被省略调用,可以用作上下文管理器:

with assert_no_gc_cycles(): do_something()

自版本 1.15.0 新增。

参数:

func可调用函数

要测试的可调用函数。

*args参数

传递给func的参数。

****kwargs**关键字参数

传递给func的关键字参数。

返回:

什么都没有。结果被有意丢弃以确保所有循环

被发现。

numpy.testing.assert_string_equal

原文:numpy.org/doc/1.26/reference/generated/numpy.testing.assert_string_equal.html

代码语言:javascript复制
testing.assert_string_equal(actual, desired)

测试两个字符串是否相等。

如果给定的字符串相等,assert_string_equal 什么也不做。 如果它们不相等,就会引发一个 AssertionError,并显示字符串之间的差异。

参数:

actualstr

要测试是否与期望字符串相等的字符串。

desiredstr

期望的字符串。

示例

代码语言:javascript复制
>>> np.testing.assert_string_equal('abc', 'abc')
>>> np.testing.assert_string_equal('abc', 'abcd')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
...
AssertionError: Differences in strings:
- abc  abcd?      

numpy.testing.assert_

原文:numpy.org/doc/1.26/reference/generated/numpy.testing.assert_.html

代码语言:javascript复制
testing.assert_(val, msg='')

断言在发布模式下起作用。接受可调用的消息以延迟到失败时再进行评估。

Python 内置的 assert 在执行优化模式的代码时不起作用(使用 -O 标志)- 它不会生成任何字节码。

有关使用方法的文档,请参考 Python 文档。

numpy.testing.assert_almost_equal

原文:numpy.org/doc/1.26/reference/generated/numpy.testing.assert_almost_equal.html

代码语言:javascript复制
testing.assert_almost_equal(actual, desired, decimal=7, err_msg='', verbose=True)

如果两个项目没有达到期望的精度,则引发 AssertionError。

注意

建议使用assert_allcloseassert_array_almost_equal_nulpassert_array_max_ulp中的一个,而不是使用此函数进行更一致的浮点数比较。

该测试验证actualdesired的元素是否满足。

abs(desired-actual) < float64(1.5 * 10**(-decimal))

这个测试比最初文档中描述的宽松,但与assert_array_almost_equal中的实际实现一致,直到舍入不确定性。在冲突值时会引发异常。对于 ndarrays,这会委托给 assert_array_almost_equal

参数:

actual类似数组

要检查的对象。

desired类似数组

预期的对象。

decimalint,可选

期望的精度,默认为 7。

err_msgstr,可选

失败时打印的错误消息。

verbosebool,可选

如果为 True,则冲突的值将附加到错误消息中。

引发:

AssertionError

如果实际和期望不等到指定精度。

另请参阅

assert_allclose

使用期望的相对和/或绝对精度比较两个类似数组对象的相等性。

assert_array_almost_equal_nulp, assert_array_max_ulp, assert_equal

示例

代码语言:javascript复制
>>> from numpy.testing import assert_almost_equal
>>> assert_almost_equal(2.3333333333333, 2.33333334)
>>> assert_almost_equal(2.3333333333333, 2.33333334, decimal=10)
Traceback (most recent call last):
  ...
AssertionError:
Arrays are not almost equal to 10 decimals
 ACTUAL: 2.3333333333333
 DESIRED: 2.33333334 
代码语言:javascript复制
>>> assert_almost_equal(np.array([1.0,2.3333333333333]),
...                     np.array([1.0,2.33333334]), decimal=9)
Traceback (most recent call last):
  ...
AssertionError:
Arrays are not almost equal to 9 decimals

Mismatched elements: 1 / 2 (50%)
Max absolute difference: 6.66669964e-09
Max relative difference: 2.85715698e-09
 x: array([1.         , 2.333333333])
 y: array([1.        , 2.33333334]) 

numpy.testing.assert_approx_equal

原文:numpy.org/doc/1.26/reference/generated/numpy.testing.assert_approx_equal.html

代码语言:javascript复制
testing.assert_approx_equal(actual, desired, significant=7, err_msg='', verbose=True)

如果两个值的值在有效数字位数上不相等,则引发 AssertionError。

注意

建议使用assert_allcloseassert_array_almost_equal_nulpassert_array_max_ulp中的一个替代本函数,以进行更一致的浮点数比较。

给定两个数字,检查它们是否近似相等。近似相等定义为一致的有效数字个数。

参数:

actualscalar

要检查的对象。

desiredscalar

期望的对象。

significantint,可选

所需精度,默认为 7。

err_msgstr,可选

失败时要打印的错误消息。

verbosebool,可选

如果为 True,则冲突的值将附加到错误消息。

引发:

AssertionError

如果实际值和期望值在指定精度内不相等。

另请参见

assert_allclose

用所需相对精度和/或绝对精度比较两个类似数组的对象是否相等。

assert_array_almost_equal_nulpassert_array_max_ulpassert_equal

示例

代码语言:javascript复制
>>> np.testing.assert_approx_equal(0.12345677777777e-20, 0.1234567e-20)
>>> np.testing.assert_approx_equal(0.12345670e-20, 0.12345671e-20,
...                                significant=8)
>>> np.testing.assert_approx_equal(0.12345670e-20, 0.12345672e-20,
...                                significant=8)
Traceback (most recent call last):
  ...
AssertionError:
Items are not equal to 8 significant digits:
 ACTUAL: 1.234567e-21
 DESIRED: 1.2345672e-21 

引发异常的计算条件是

代码语言:javascript复制
>>> abs(0.12345670e-20/1e-21 - 0.12345672e-20/1e-21) >= 10**-(8-1)
True 

numpy.testing.assert_array_almost_equal

原文:numpy.org/doc/1.26/reference/generated/numpy.testing.assert_array_almost_equal.html

代码语言:javascript复制
testing.assert_array_almost_equal(x, y, decimal=6, err_msg='', verbose=True)

如果两个对象不相等到所需的精度,则引发断言错误。

注意

建议使用assert_allclose之一,而不是使用此函数进行更一致的浮点比较assert_array_almost_equal_nulpassert_array_max_ulp

测试验证actualdesired的元素满足相同的形状和。

abs(desired-actual) < 1.5 * 10**(-decimal)

这是一个比最初记录的测试宽松的测试,但与实际实现的结果到四舍五入的差异一致。在形状不匹配或存在冲突值时引发异常。与 numpy 中的标准用法相反,NaN 与数字进行比较,如果两个对象在相同位置具有 NaN,则不会引发断言。

Parameters:

xarray_like

要检查的实际对象。

yarray_like

所需的,期望的对象。

decimalint, optional

所需的精度,默认为 6。

err_msgstr, optional

失败时要打印的错误消息。

verbosebool, optional

如果为 True,则冲突的值将追加到错误消息中。

Raises:

断言错误

如果实际和期望的不等直至指定精度。

另请参阅

assert_allclose

用所需的相对和/或绝对精度比较两个array_like对象的相等性。

assert_array_almost_equal_nulp, assert_array_max_ulp, assert_equal

示例

第一个 assert 不会引发异常

代码语言:javascript复制
>>> np.testing.assert_array_almost_equal([1.0,2.333,np.nan],
...                                      [1.0,2.333,np.nan]) 
代码语言:javascript复制
>>> np.testing.assert_array_almost_equal([1.0,2.33333,np.nan],
...                                      [1.0,2.33339,np.nan], decimal=5)
Traceback (most recent call last):
  ...
AssertionError:
Arrays are not almost equal to 5 decimals

Mismatched elements: 1 / 3 (33.3%)
Max absolute difference: 6.e-05
Max relative difference: 2.57136612e-05
 x: array([1.     , 2.33333,     nan])
 y: array([1.     , 2.33339,     nan]) 
代码语言:javascript复制
>>> np.testing.assert_array_almost_equal([1.0,2.33333,np.nan],
...                                      [1.0,2.33333, 5], decimal=5)
Traceback (most recent call last):
  ...
AssertionError:
Arrays are not almost equal to 5 decimals

x and y nan location mismatch:
 x: array([1.     , 2.33333,     nan])
 y: array([1.     , 2.33333, 5.     ]) 

numpy.testing.print_assert_equal

原文:numpy.org/doc/1.26/reference/generated/numpy.testing.print_assert_equal.html

代码语言:javascript复制
testing.print_assert_equal(test_string, actual, desired)

测试两个对象是否相等,如果测试失败则打印错误消息。

测试使用 actual == desired 进行。

参数:

测试字符串str

提供给 AssertionError 的消息。

实际值对象

要根据期望值进行相等性测试的对象。

期望值对象

期望的结果。

示例

代码语言:javascript复制
>>> np.testing.print_assert_equal('Test XYZ of func xyz', [0, 1], [0, 1])
>>> np.testing.print_assert_equal('Test XYZ of func xyz', [0, 1], [0, 2])
Traceback (most recent call last):
...
AssertionError: Test XYZ of func xyz failed
ACTUAL:
[0, 1]
DESIRED:
[0, 2] 

numpy.testing.decorate_methods

原文:numpy.org/doc/1.26/reference/generated/numpy.testing.decorate_methods.html

代码语言:javascript复制
testing.decorate_methods(cls, decorator, testmatch=None)

将装饰器应用于类中匹配正则表达式的所有方法。

给定的装饰器应用于所有由正则表达式testmatch匹配的cls的公共方法(testmatch.search(methodname))。以下划线开头的私有方法将被忽略。

参数:

cls

要装饰方法的类。

decorator函数

要应用装饰器的方法

testmatch编译后的正则表达式或字符串,可选

正则表达式。默认值为 None,此时使用 nose 默认值(re.compile(r'(?:^|[b_.%s-])[Tt]est' % os.sep))。如果testmatch是一个字符串,则首先将其编译为正则表达式。

numpy.testing.clear_and_catch_warnings

原文:numpy.org/doc/1.26/reference/generated/numpy.testing.clear_and_catch_warnings.html

代码语言:javascript复制
class numpy.testing.clear_and_catch_warnings(record=False, modules=())

重置警告注册表以捕获警告的上下文管理器

警告可能很棘手,因为每当触发警告时,Python 会在calling模块中添加一个__warningregistry__成员。这使得在此模块中无法重新触发警告,无论您在警告过滤器中放置什么。此上下文管理器在其构造函数中接受modules的序列作为关键字参数,并:

  • 在进入时存储和删除给定modules中的任何__warningregistry__条目;
  • 在退出时将__warningregistry__重置为其先前状态。

这样可以在上下文管理器内部触发任何警告,而不会干扰外部警告的状态。

为了与 Python 3.0 兼容,请考虑所有参数只能是关键字参数。

参数:

recordbool,可选

指定是否应该由warnings.showwarning()的自定义实现捕获警告,并将其附加到上下文管理器返回的列表中。否则,上下文管理器将返回 None。附加到列表的对象是参数,其属性反映了showwarning()的参数。

modules序列,可选

重置警告注册表以便在进入时重置警告注册表的模块序列,退出时恢复警告注册表。为了正常工作,所有的“ignore”过滤器都应该按照这些模块之一进行过滤。

示例

代码语言:javascript复制
>>> import warnings
>>> with np.testing.clear_and_catch_warnings(
...         modules=[np.core.fromnumeric]):
...     warnings.simplefilter('always')
...     warnings.filterwarnings('ignore', module='np.core.fromnumeric')
...     # do something that raises a warning but ignore those in
...     # np.core.fromnumeric 

numpy.testing.measure

原文:numpy.org/doc/1.26/reference/generated/numpy.testing.measure.html

代码语言:javascript复制
testing.measure(code_str, times=1, label=None)

返回调用者命名空间中执行代码所经过的时间。

提供的代码字符串使用 Python 内建的 compile 进行编译。计时的精度是 10 毫秒。如果代码在这个时间尺度上执行得很快,它可以多次执行,以获得合理的计时精度。

参数:

code_str 字符串

要进行计时的代码。

times 整数,可选

代码执行的次数。默认值为 1。代码只编译一次。

label 字符串,可选

用于标识 code_str 的标签。它作为 compile 的第二个参数传入(用于运行时错误消息)。

返回:

elapsed 浮点数

执行 code_str times 次的总经过时间,单位为秒。

示例

代码语言:javascript复制
>>> times = 10
>>> etime = np.testing.measure('for i in range(1000): np.sqrt(i**2)', times=times)
>>> print("Time for a single execution : ", etime / times, "s")  
Time for a single execution :  0.005 s 

numpy.testing.rundocs

链接:numpy.org/doc/1.26/reference/generated/numpy.testing.rundocs.html

代码语言:javascript复制
testing.rundocs(filename=None, raise_on_error=True)

运行给定文件中的文档测试。

默认情况下,rundocs在失败时会引发一个 AssertionError。

参数:

filenamestr

要运行文档测试的文件路径。

raise_on_errorbool

是否在文档测试失败时引发 AssertionError。默认为 True。

注释

用户/开发者可以通过在test()调用中添加doctests参数来运行文档测试。例如,要运行所有测试(包括文档测试)fornumpy.lib

代码语言:javascript复制
>>> np.lib.test(doctests=True) 

numpy.testing.suppress_warnings

原文:numpy.org/doc/1.26/reference/generated/numpy.testing.suppress_warnings.html

代码语言:javascript复制
class numpy.testing.suppress_warnings(forwarding_rule='always')

上下文管理器和装饰器的功能与warnings.catch_warnings类似。

然而,这也提供了一种解决bugs.python.org/issue4180的过滤机制。

这个 bug 导致 Python 3.4 之前的版本在被忽略一次后无法可靠地再次显示警告(即使在 catch_warnings 内部)。这意味着很难使用“ignore”过滤器,因为后续的测试可能需要查看警告。此外,它允许更容易地针对测试警告进行特定设置,还可嵌套使用。

参数:

forwarding_rulestr, optional

选择“always”、“once”、“module”或“location”之一。类似于常规警告模块的过滤模式,有助于减少大部分噪音的输出。未抑制和未记录的警告将根据此规则转发。默认为“always”。“location”相当于警告的“default”,根据警告来源的确切位置匹配。

注意事项

在上下文管理器内添加的过滤器在退出时将被丢弃。进入时将自动应用所有在上层定义的过滤器。

当添加记录过滤器时,匹配的警告将存储在log属性中,以及在record返回的列表中。

如果添加了过滤器并提供了module关键字,则在应用、进入上下文或退出上下文时还将清除此模块的警告注册表。如果配置为仅打印一次(默认)并且在进入上下文之前已经打印过,则可能导致警告再次显示。

嵌套此上下文管理器在“always”(默认)的转发规则下能正常工作。未经过滤和未记录的警告将被传递出去,并由外层级别匹配。在最外层级别上,它们将被打印(或被另一个警告上下文捕获)。转发规则参数可以修改这种行为。

类似于catch_warnings,此上下文管理器不支持多线程。

示例

使用上下文管理器:

代码语言:javascript复制
with np.testing.suppress_warnings() as sup:
    sup.filter(DeprecationWarning, "Some text")
    sup.filter(module=np.ma.core)
    log = sup.record(FutureWarning, "Does this occur?")
    command_giving_warnings()
    # The FutureWarning was given once, the filtered warnings were
    # ignored. All other warnings abide outside settings (may be
    # printed/error)
    assert_(len(log) == 1)
    assert_(len(sup.log) == 1)  # also stored in log attribute 

或者作为装饰器:

代码语言:javascript复制
sup = np.testing.suppress_warnings()
sup.filter(module=np.ma.core)  # module must match exactly
@sup
def some_function():
    # do something which causes a warning in np.ma.core
    pass 

方法

__call__(func)

函数装饰器,可将某些抑制应用于整个函数。

filter([category, message, module])

添加一个新的抑制过滤器,或者在状态进入时应用它。

record([category, message, module])

追加一个新的记录过滤器,或者在状态进入时应用它。

测试准则

原文:numpy.org/doc/1.26/reference/testing.html

介绍

直到 1.15 版本,NumPy 使用了nose测试框架,现在使用pytest框架。老的框架仍在维护,以支持使用旧 numpy 框架的下游项目,但所有 NumPy 的测试应该使用 pytest。

我们的目标是 NumPy 中的每个模块和包都应该有一套全面的单元测试。这些测试应该对给定例程的全部功能进行测试,以及对错误或意外输入参数的鲁棒性。设计良好且覆盖率良好的测试对于重构的易用性有着巨大的影响。每当发现例程中的新 bug 时,您应该为该特定情况编写一个新的测试,并将其添加到测试套件中,以防止该 bug 不经意地再次回归。

注意

SciPy 使用numpy.testing中的测试框架,因此下面显示的所有 NumPy 示例也适用于 SciPy

测试 NumPy

NumPy 可以以多种方式进行测试,选择您感到舒适的任何方式。

从 Python 内部运行测试

您可以通过numpy.test测试已安装的 NumPy,例如,要运行 NumPy 的全面测试套件,请使用以下命令:

代码语言:javascript复制
>>> import numpy
>>> numpy.test(label='slow') 

测试方法可能需要两个或更多参数;第一个label是一个指定应该被测试的内容的字符串,第二个verbose是一个给出输出详细程度的整数。参见 docstring numpy.test获取详情。label的默认值为’fast’ - 运行标准测试。字符串’full’将运行全部测试,包括那些被识别为运行缓慢的测试。如果verbose为 1 或更小,则测试将只显示有关运行的测试的信息消息;但如果大于 1,则测试还将提供有关缺少测试的警告。因此,如果要运行每个测试并获取有关哪些模块没有测试的消息:

代码语言:javascript复制
>>> numpy.test(label='full', verbose=2)  # or numpy.test('full', 2) 

最后,如果您只对测试 NumPy 的一个子集感兴趣,例如core模块,请使用以下命令:

代码语言:javascript复制
>>> numpy.core.test() 
从命令行运行测试

如果要构建 NumPy 以便对 NumPy 本身进行工作,请使用spin工具。要运行 NumPy 的全面测试套件:

代码语言:javascript复制
$ spin test -m full 

测试 NumPy 的一个子集:

代码语言:javascript复制
$ spin test -t numpy/core/tests 

有关测试的详细信息,请参阅测试构建

其他运行测试的方法

使用您喜爱的 IDE(例如vscode或pycharm)运行测试

撰写您自己的测试

如果你正在编写一个希望成为 NumPy 一部分的包,请在开发包的同时编写测试。NumPy 包目录中的每个 Python 模块、扩展模块或子包都应有一个相应的test_<name>.py文件。Pytest 会检查这些文件以寻找测试方法(命名为test*)和测试类(命名为Test*)。

假设你有一个 NumPy 模块numpy/xxx/yyy.py,其中包含一个函数zzz()。为了测试这个函数,你会创建一个名为test_yyy.py的测试模块。如果你只需要测试zzz的一个方面,你可以简单地添加一个测试函数:

代码语言:javascript复制
def test_zzz():
    assert zzz() == 'Hello from zzz' 

更常见的是,我们需要将多个测试组合在一起,因此我们创建一个测试类:

代码语言:javascript复制
import pytest

# import xxx symbols
from numpy.xxx.yyy import zzz
import pytest

class TestZzz:
    def test_simple(self):
        assert zzz() == 'Hello from zzz'

    def test_invalid_parameter(self):
        with pytest.raises(ValueError, match='.*some matching regex.*'):
            ... 

在这些测试方法中,使用assert和相关函数来测试某个假设是否成立。如果断言失败,测试也失败。pytest在内部重写assert语句,以在失败时提供信息性的输出,因此应优先使用它而不是旧版的numpy.testing.assert_。而在使用-O标志以优化模式运行 Python 时,普通的assert语句会被忽略,但在使用 pytest 运行测试时,这并不是一个问题。

类似地,应优先使用 pytest 函数pytest.raisespytest.warns而不是它们的旧版对应物numpy.testing.assert_raisesnumpy.testing.assert_warns,因为 pytest 的变体更广泛使用,并在与match正则表达式一起使用时允许更明确地定位警告和错误。

注意,test_函数或方法不应该有文档字符串,因为这会使得在使用verbose=2(或类似的详细设置)运行测试套件时难以识别测试。必要时使用普通的注释(#)。

同样,由于很多 NumPy 代码是没有单元测试的传统代码,仍然有几个模块尚未进行测试。请随意选择其中一个模块并为其开发测试。

在测试中使用 C 代码

NumPy 暴露了丰富的 C-API。这些是使用 c 扩展模块编写的,其“仿佛”不知道 NumPy 内部结构,而只使用官方 C-API 接口进行测试。这样的模块示例包括用户定义的rational dtype 的测试在_rational_tests中,或二进制发行版中的 ufunc 机制测试在_umath_tests中。从 1.21 版本开始,你还可以在测试中编写一些 C 代码,这些代码将在本地编译为 c 扩展模块并加载到 Python 中。

代码语言:javascript复制
numpy.testing.extbuild.build_and_import_extension(modname, functions, *, prologue='', build_dir=None, include_dirs=[], more_init='')

从函数片段functions列表中构建和导入 c 扩展模块modname

参数:

函数片段列表

每个片段都是一个 func_name、调用约定、片段的序列。

序言字符串

通常在其余部分之前的代码,通常是额外的#include#define宏。

build_dirpathlib.Path

在哪里构建模块,通常是一个临时目录

include_dirs列表

编译时额外的目录查找包括文件

more_init字符串

出现在模块 PyMODINIT_FUNC 中的代码

返回:

输出:模块

模块已被加载并准备好使用

示例

代码语言:javascript复制
>>> functions = [("test_bytes", "METH_O", """
 if ( !PyBytesCheck(args)) {
 Py_RETURN_FALSE;
 }
 Py_RETURN_TRUE;
""")]
>>> mod = build_and_import_extension("testme", functions)
>>> assert not mod.test_bytes(u'abc')
>>> assert mod.test_bytes(b'abc') 
标记测试

像上面的未加标签的测试一样,会在默认的numpy.test()运行中运行。如果您想将测试标记为慢 - 因此保留给完整的numpy.test(label='full')运行,您可以使用pytest.mark.slow进行标记:

代码语言:javascript复制
import pytest

@pytest.mark.slow
def test_big(self):
    print('Big, slow test') 

同样对于方法:

代码语言:javascript复制
class test_zzz:
    @pytest.mark.slow
    def test_simple(self):
        assert_(zzz() == 'Hello from zzz') 
更容易的设置和拆卸函数/方法

Testing 会按名称查找模块级或类方法级设置和拆卸功能;因此:

代码语言:javascript复制
def setup_module():
  """Module-level setup"""
    print('doing setup')

def teardown_module():
  """Module-level teardown"""
    print('doing teardown')

class TestMe:
    def setup_method(self):
  """Class-level setup"""
        print('doing setup')

    def teardown_method():
  """Class-level teardown"""
        print('doing teardown') 

设置和拆卸功能和方法被称为“fixtures”,应该谨慎使用。pytest支持各种作用域的更一般的 fixture,可以通过特殊参数自动使用。例如,在测试中使用特殊参数名tmpdir来创建临时目录。

参数化测试

测试的一个非常好的特性是允许跨一系列参数轻松进行测试 - 这对于标准单元测试来说是一个棘手的问题。使用pytest.mark.parametrize装饰器。

Doctests

Doctests 是一种方便的方式来记录函数的行为并允许同时测试该行为。交互式 Python 会话的输出可以包含在函数的文档字符串中,测试框架可以运行示例并将实际输出与预期输出进行比较。

可以通过在test()调用中添加doctests参数来运行 Doctests;例如,要运行 numpy.lib 的所有测试(包括 Doctests):

代码语言:javascript复制
>>> import numpy as np
>>> np.lib.test(doctests=True) 

和这些测试一样,Doctests 会被视为在已经执行了import numpy as np的新 Python 实例中运行。属于 NumPy 子包的测试将已经导入该子包。例如,对于numpy/linalg/tests/中的测试,将创建命名空间,以便from numpy import linalg已经执行。

tests/

相比将代码和测试放在同一个目录中,我们将给定子包的所有测试放在一个tests/子目录中。例如,对于我们的示例,如果numpy/xxx/中尚不存在该目录,则需要创建一个tests/目录。因此,test_yyy.py的路径是numpy/xxx/tests/test_yyy.py

一旦编写了numpy/xxx/tests/test_yyy.py,可以通过转到tests/目录并键入以下内容来运行测试:

代码语言:javascript复制
python test_yyy.py 

或者,如果您将numpy/xxx/tests/添加到 Python 路径中,也可以在解释器中交互式地运行测试,就像这样:

代码语言:javascript复制
>>> import test_yyy
>>> test_yyy.test() 
__init__.pysetup.py

通常,将tests/目录添加到 Python 路径中并不理想。相反,最好直接从模块xxx中调用测试。为此,只需将以下行放置在包的__init__.py文件的末尾:

代码语言:javascript复制
...
def test(level=1, verbosity=1):
    from numpy.testing import Tester
    return Tester().test(level, verbosity) 

您还需要在 setup.py 的配置部分中添加测试目录:

代码语言:javascript复制
...
def configuration(parent_package='', top_path=None):
    ...
    config.add_subpackage('tests')
    return config
... 

现在,您可以执行以下操作来测试您的模块:

代码语言:javascript复制
>>> import numpy
>>> numpy.xxx.test() 

此外,在调用整个 NumPy 测试套件时,将找到并运行您的测试:

代码语言:javascript复制
>>> import numpy
>>> numpy.test()
# your tests are included and run automatically! 

技巧与窍门

创建许多类似的测试

如果您有一组必须以轻微变化运行多次的测试,那么创建一个包含所有公共测试的基类,然后为每个变化创建一个子类可能会有所帮助。NumPy 中存在几个此技术的示例;以下是来自numpy/linalg/tests/test_linalg.py的摘录:

代码语言:javascript复制
class LinalgTestCase:
    def test_single(self):
        a = array([[1., 2.], [3., 4.]], dtype=single)
        b = array([2., 1.], dtype=single)
        self.do(a, b)

    def test_double(self):
        a = array([[1., 2.], [3., 4.]], dtype=double)
        b = array([2., 1.], dtype=double)
        self.do(a, b)

    ...

class TestSolve(LinalgTestCase):
    def do(self, a, b):
        x = linalg.solve(a, b)
        assert_allclose(b, dot(a, x))
        assert imply(isinstance(b, matrix), isinstance(x, matrix))

class TestInv(LinalgTestCase):
    def do(self, a, b):
        a_inv = linalg.inv(a)
        assert_allclose(dot(a, a_inv), identity(asarray(a).shape[0]))
        assert imply(isinstance(a, matrix), isinstance(a_inv, matrix)) 

在这种情况下,我们想要测试使用几种数据类型的矩阵来解决线性代数问题,使用linalg.solvelinalg.inv。常见的测试用例(用于单精度、双精度等矩阵)收集在LinalgTestCase中。

已知失败与跳过测试

有时您可能希望跳过测试或将其标记为已知失败,例如当测试套件在编写它的代码之前,或者如果测试仅在特定架构上失败时。

要跳过一个测试,只需使用skipif

代码语言:javascript复制
import pytest

@pytest.mark.skipif(SkipMyTest, reason="Skipping this test because...")
def test_something(foo):
    ... 

如果SkipMyTest评估为非零,则将测试标记为跳过,并且详细测试输出中的消息是给定给skipif的第二个参数。类似地,可以使用xfail将测试标记为已知失败:

代码语言:javascript复制
import pytest

@pytest.mark.xfail(MyTestFails, reason="This test is known to fail because...")
def test_something_else(foo):
    ... 

当然,可以使用skipxfail无条件地跳过测试或将其标记为已知失败,而不带参数。

测试运行结束时会显示跳过和已知失败测试的总数。跳过的测试在测试结果中标记为'S'(对于verbose > 1,标记为'SKIPPED'),已知失败的测试标记为'x'(或对于verbose > 1,标记为'XFAIL')。

随机数据的测试

随机数据的测试很好,但由于测试失败旨在暴露新的错误或回归,因此一个大部分时间都通过但偶尔在没有代码更改的情况下失败的测试是没有帮助的。通过在生成随机数据之前设置随机数种子来使随机数据具有确定性。使用 Python 的random.seed(some_number)或 NumPy 的numpy.random.seed(some_number),取决于随机数的来源。

或者,您可以使用Hypothesis生成任意数据。Hypothesis 为您管理 Python 和 NumPy 的随机种子,并提供一种非常简洁和强大的描述数据的方式(包括hypothesis.extra.numpy,例如一组互相广播的形状)。

与随机生成相比的优势包括工具,可以在不需要固定种子的情况下重新播放和共享失败,为每次失败报告最小示例,并且触发错误的技术优于朴素的随机技术。

用于numpy.test的文档
代码语言:javascript复制
numpy.test(label='fast', verbose=1, extra_argv=None, doctests=False, coverage=False, durations=-1, tests=None)

Pytest 测试运行器。

通常将测试函数添加到软件包的 init.py 中,如下所示:

代码语言:javascript复制
from numpy._pytesttester import PytestTester
test = PytestTester(__name__).test
del PytestTester 

调用此测试函数会查找并运行与模块及其所有子模块相关的所有测试。

参数:

module_namemodule name

要测试的模块的名称。

备注

与先前基于nose的实现不同,该类不是公开的,因为它执行了一些numpy特定的警告抑制。

属性:

module_namestr

要测试的软件包的完整路径。

介绍

在 1.15 版本之前,NumPy 使用了 nose 测试框架,现在使用 pytest 框架。旧框架仍然得到维护,以支持使用旧 numpy 框架的下游项目,但所有 NumPy 的测试都应该使用 pytest。

我们的目标是,NumPy 中的每个模块和包都应该有一套完善的单元测试。这些测试应该在给定例程的全功能性以及对错误或意外输入参数的鲁棒性方面进行测试。设计良好且覆盖率良好的测试对于重构的便利性有着巨大影响。每当在例程中发现新错误时,您应该为该特定情况编写一个新的测试,并将其添加到测试套件中,以防止该错误不经意地潜回。

注意

SciPy 使用来自numpy.testing的测试框架,因此下面显示的所有 NumPy 示例也适用于 SciPy。

测试 NumPy

NumPy 可以以多种方式进行测试,选择您感到舒适的任何方式。

从 Python 内部运行测试

您可以通过numpy.test来测试已安装的 NumPy,例如,要运行 NumPy 的完整测试套件,请使用以下方法:

代码语言:javascript复制
>>> import numpy
>>> numpy.test(label='slow') 

测试方法可能需要两个或多个参数;第一个label是一个指定应该进行测试的字符串,第二个verbose是一个整数,表示输出冗余级别。有关详细信息,请参见 docstring numpy.testlabel的默认值为‘fast’ - 这将运行标准测试。字符串‘full’将运行完整的测试套件,包括被标识为运行缓慢的测试。如果verbose为 1 或更少,测试将只显示有关运行的测试的信息消息;但如果大于 1,则测试还将提供有关缺少测试的警告。因此,如果您想运行每个测试并获取有关哪些模块没有测试的消息:

代码语言:javascript复制
>>> numpy.test(label='full', verbose=2)  # or numpy.test('full', 2) 

最后,如果您只对测试 NumPy 的子集感兴趣,例如core模块,请使用以下方法:

代码语言:javascript复制
>>> numpy.core.test() 
从命令行运行测试

如果你想构建 NumPy 以便在 NumPy 本身上工作,请使用spin实用程序。要运行 NumPy 的完整测试套件:

代码语言:javascript复制
$ spin test -m full 

测试 NumPy 的子集:

代码语言:javascript复制
$ spin test -t numpy/core/tests 

有关测试的详细信息,请参阅测试构建

其他运行测试的方法

使用你最喜欢的 IDE,比如vscode或pycharm来运行测试

从 Python 内部运行测试

你可以通过numpy.test来测试安装的 NumPy,例如,要运行 NumPy 的完整测试套件,请使用以下命令:

代码语言:javascript复制
>>> import numpy
>>> numpy.test(label='slow') 

测试方法可能需要两个或更多参数;第一个label是一个字符串,指定应该测试什么,第二个verbose是一个整数,表示输出详细程度。有关详细信息,请参阅numpy.test的文档字符串。label的默认值是’fast’ - 这将运行标准测试。字符串’full’将运行所有测试,包括标识为运行缓慢的测试。如果verbose为 1 或更低,则测试将仅显示有关运行的测试的信息消息;但如果大于 1,则测试还将提供有关缺少测试的警告。所以如果你想运行每个测试并得到关于哪些模块没有测试的消息:

代码语言:javascript复制
>>> numpy.test(label='full', verbose=2)  # or numpy.test('full', 2) 

最后,如果你只对测试 NumPy 的子集感兴趣,比如core模块,可以使用以下命令:

代码语言:javascript复制
>>> numpy.core.test() 
从命令行运行测试

如果你想构建 NumPy 以便在 NumPy 本身上工作,请使用spin实用程序。要运行 NumPy 的完整测试套件:

代码语言:javascript复制
$ spin test -m full 

测试 NumPy 的子集:

代码语言:javascript复制
$ spin test -t numpy/core/tests 

有关测试的详细信息,请参阅测试构建

其他运行测试的方法

使用你最喜欢的 IDE,比如vscode或pycharm来运行测试

编写你自己的测试

如果你正在编写一个希望成为 NumPy 一部分的软件包,请在开发软件包时编写测试。NumPy 软件包目录中的每个 Python 模块、扩展模块或子软件包都应该有一个对应的test_<name>.py文件。Pytest 会检查这些文件中的测试方法(命名为test*)和测试类(命名为Test*)。

假设你有一个 NumPy 模块numpy/xxx/yyy.py,其中包含一个函数zzz()。要测试这个函数,你需要创建一个名为test_yyy.py的测试模块。如果你只需要测试zzz的一个方面,你可以简单地添加一个测试函数:

代码语言:javascript复制
def test_zzz():
    assert zzz() == 'Hello from zzz' 

更多时候,我们需要将许多测试组合在一起,因此创建一个测试类:

代码语言:javascript复制
import pytest

# import xxx symbols
from numpy.xxx.yyy import zzz
import pytest

class TestZzz:
    def test_simple(self):
        assert zzz() == 'Hello from zzz'

    def test_invalid_parameter(self):
        with pytest.raises(ValueError, match='.*some matching regex.*'):
            ... 

在这些测试方法中,使用assert和相关函数来测试某个假设是否有效。如果断言失败,则测试失败。pytest在内部重写assert语句以在失败时给出信息性的输出,因此应该优先使用它而不是遗留的变体numpy.testing.assert_。而在使用-O参数以优化模式运行 Python 时,简单的assert语句将被忽略,但在使用 pytest 运行测试时不会出现这个问题。

同样地,应该优先使用 pytest 函数pytest.raisespytest.warns,而不是遗留的对应项numpy.testing.assert_raisesnumpy.testing.assert_warns,因为 pytest 的变体更广泛地被使用,并允许与match正则表达式一起更明确地定位警告和错误。

请注意,test_函数或方法不应该有文档字符串,因为这样会使得在使用verbose=2(或类似的详细程度设置)运行测试套件的输出中很难识别测试。必要时使用纯注释(#)。

另外,由于 NumPy 的大部分代码都是没有经过单元测试的遗留代码,仍然有几个模块尚未经过测试。请随意选择其中一个模块并为其开发测试。

在测试中使用 C 代码

NumPy 公开了丰富的 C-API。这些是使用 c 扩展模块进行测试的,这些模块被编写得就像它们对 NumPy 的内部一无所知一样,而只是使用官方的 C-API 接口。这些模块的示例包括_rational_tests中对用户定义的rational数据类型的测试,以及二进制发布包中的一部分——在_umath_tests中的 ufunc 机制测试。从 1.21 版本开始,您还可以在测试中编写一小段 C 代码,该代码将被本地编译为 c 扩展模块,并加载到 python 中。

代码语言:javascript复制
numpy.testing.extbuild.build_and_import_extension(modname, functions, *, prologue='', build_dir=None, include_dirs=[], more_init='')

从片段列表functions中构建并导入 c 扩展模块modname

参数:

functions片段列表

每个片段都是一个 func_name,调用约定,片段的序列。

prologuestring

出现在其余部分之前的代码,通常是额外的#include#define

build_dirpathlib.Path

模块的构建目录,通常是临时目录

include_dirslist

编译时查找包含文件的额外目录

more_initstring

出现在模块 PyMODINIT_FUNC 中的代码

返回:

out: 模块

模块已加载并准备就绪

示例

代码语言:javascript复制
>>> functions = [("test_bytes", "METH_O", """
 if ( !PyBytesCheck(args)) {
 Py_RETURN_FALSE;
 }
 Py_RETURN_TRUE;
""")]
>>> mod = build_and_import_extension("testme", functions)
>>> assert not mod.test_bytes(u'abc')
>>> assert mod.test_bytes(b'abc') 
测试标签

像上面那样未标记的测试会在默认的 numpy.test() 运行中运行。如果要将测试标记为慢速 - 因此保留给完整的 numpy.test(label='full') 运行,则可以使用 pytest.mark.slow 标记它:

代码语言:javascript复制
import pytest

@pytest.mark.slow
def test_big(self):
    print('Big, slow test') 

对于方法也是类似的:

代码语言:javascript复制
class test_zzz:
    @pytest.mark.slow
    def test_simple(self):
        assert_(zzz() == 'Hello from zzz') 
更容易的设置和拆卸函数/方法

测试通过名称查找模块级别或类方法级别的设置和拆卸函数;因此:

代码语言:javascript复制
def setup_module():
  """Module-level setup"""
    print('doing setup')

def teardown_module():
  """Module-level teardown"""
    print('doing teardown')

class TestMe:
    def setup_method(self):
  """Class-level setup"""
        print('doing setup')

    def teardown_method():
  """Class-level teardown"""
        print('doing teardown') 

将函数和方法的设置和拆卸函数称为“固件”,并且应该谨慎使用。pytest 支持各种作用域的更通用的固件,可以通过特殊参数自动使用。例如,特殊参数名称 tmpdir 用于在测试中创建临时目录。

参数化测试

测试的一个非常好的特性是允许轻松地在一系列参数上进行测试 - 这对于标准单元测试来说是一个讨厌的问题。使用 pytest.mark.parametrize 装饰器。

Doctests

Doctests 是一种方便的方式,用于记录函数的行为并同时允许测试该行为。交互式 Python 会话的输出可以包含在函数的文档字符串中,测试框架可以运行示例并将实际输出与预期输出进行比较。

可以通过将 doctests 参数添加到 test() 调用中来运行 doctests;例如,要运行 numpy.lib 的所有测试(包括 doctests):

代码语言:javascript复制
>>> import numpy as np
>>> np.lib.test(doctests=True) 

doctests 被运行,就好像它们在一个已执行 import numpy as np 的新的 Python 实例中一样。作为 NumPy 子包的一部分的测试将已经导入该子包。例如,在 numpy/linalg/tests/ 中的测试中,将创建命名空间,使得 from numpy import linalg 已经执行。

tests/

与其将代码和测试保存在同一个目录中,不如将给定子包的所有测试放在一个 tests/ 子目录中。对于我们的示例,如果尚不存在,您将需要在 numpy/xxx/ 中创建一个 tests/ 目录。因此,test_yyy.py 的路径是 numpy/xxx/tests/test_yyy.py

一旦编写了 numpy/xxx/tests/test_yyy.py,就可以转到 tests/ 目录并键入以下内容来运行测试:

代码语言:javascript复制
python test_yyy.py 

或者,如果将 numpy/xxx/tests/ 添加到 Python 路径中,可以像这样在解释器中交互式运行测试:

代码语言:javascript复制
>>> import test_yyy
>>> test_yyy.test() 
__init__.pysetup.py

通常,将 tests/ 目录添加到 Python 路径不是一个理想的做法。相反,最好直接从模块 xxx 调用测试。为此,只需将以下行放在包的 __init__.py 文件的末尾:

代码语言:javascript复制
...
def test(level=1, verbosity=1):
    from numpy.testing import Tester
    return Tester().test(level, verbosity) 

您还需要在 setup.py 的配置部分中添加 tests 目录:

代码语言:javascript复制
...
def configuration(parent_package='', top_path=None):
    ...
    config.add_subpackage('tests')
    return config
... 

现在,您可以执行以下操作来测试您的模块:

代码语言:javascript复制
>>> import numpy
>>> numpy.xxx.test() 

此外,在调用整个 NumPy 测试套件时,将找到并运行您的测试:

代码语言:javascript复制
>>> import numpy
>>> numpy.test()
# your tests are included and run automatically! 
在测试中使用 C 代码

NumPy 提供了丰富的 C-API . 使用这些时会使用基于官方 C-API 接口编写的 c 扩展模块进行测试,这些模块“好像”对 NumPy 的内部一无所知。这样的模块示例包括 _rational_tests 中针对用户定义的 rational dtype 的测试,或者 _umath_tests 中的 ufunc 机制测试,这些都是二进制分发的一部分。从版本 1.21 开始,您还可以在测试中编写一些 C 代码片段,这些代码片段将在本地编译成 c 扩展模块并加载到 python 中。

代码语言:javascript复制
numpy.testing.extbuild.build_and_import_extension(modname, functions, *, prologue='', build_dir=None, include_dirs=[], more_init='')

从函数片段列表 functions 中构建并导入 c 扩展模块 modname

参数:

functions函数片段列表

每个片段是一个函数名、调用约定、代码片段的序列。

prologue字符串

前面加上的代码,通常是额外的 #include#define 宏。

build_dirpathlib.Path

模块构建位置,通常为临时目录

include_dirs列表

编译时查找包含文件的额外目录

more_init字符串

出现在模块 PyMODINIT_FUNC 中的代码

返回:

输出:模块

模块已经加载并准备就绪

示例

代码语言:javascript复制
>>> functions = [("test_bytes", "METH_O", """
 if ( !PyBytesCheck(args)) {
 Py_RETURN_FALSE;
 }
 Py_RETURN_TRUE;
""")]
>>> mod = build_and_import_extension("testme", functions)
>>> assert not mod.test_bytes(u'abc')
>>> assert mod.test_bytes(b'abc') 
标记测试

类似上述的无标签测试会在默认的 numpy.test() 运行中运行。如果要将测试标记为慢速 - 因此保留为完整的 numpy.test(label='full') 运行,可以使用 pytest.mark.slow 进行标记:

代码语言:javascript复制
import pytest

@pytest.mark.slow
def test_big(self):
    print('Big, slow test') 

同样适用于方法:

代码语言:javascript复制
class test_zzz:
    @pytest.mark.slow
    def test_simple(self):
        assert_(zzz() == 'Hello from zzz') 
更容易的设置和拆卸函数/方法

测试会根据名称查找模块级或类方法级的设置和拆卸函数;因此:

代码语言:javascript复制
def setup_module():
  """Module-level setup"""
    print('doing setup')

def teardown_module():
  """Module-level teardown"""
    print('doing teardown')

class TestMe:
    def setup_method(self):
  """Class-level setup"""
        print('doing setup')

    def teardown_method():
  """Class-level teardown"""
        print('doing teardown') 

为函数和方法的设置和拆卸函数称为“ fixtures”,应该谨慎使用。pytest 支持各种范围的通用 fixture,可以通过特殊参数自动使用。例如,测试中使用的特殊参数名称 tmpdir 用于创建临时目录。

参数化测试

一个非常好的测试功能是允许在一系列参数上进行轻松测试 - 这对于标准单元测试来说是一项麻烦的问题。使用 pytest.mark.parametrize 装饰器。

文档测试

Doctest(文档测试)是一种方便的方式来记录函数的行为,并同时允许对该行为进行测试。可以将交互式 Python 会话的输出包含在函数的文档字符串中,测试框架可以运行示例并将实际输出与预期输出进行比较。

可以通过将 doctests 参数添加到 test() 调用中来运行文档测试;例如,要运行 numpy.lib 的所有测试(包括文档测试):

代码语言:javascript复制
>>> import numpy as np
>>> np.lib.test(doctests=True) 

文档测试会被视为在一个全新的已执行 import numpy as np 的 Python 实例中运行。作为 NumPy 子包一部分的测试将已经导入该子包。例如,在 numpy/linalg/tests/ 中的一个测试中,已经创建了这样的命名空间,以便 from numpy import linalg 已经执行。

tests/

而不是将代码和测试放在同一目录中,我们将给定子包的所有测试放入tests/子目录中。例如,对于我们的示例,如果numpy/xxx/中没有tests/目录,您需要创建一个tests/目录。因此,test_yyy.py的路径是numpy/xxx/tests/test_yyy.py

写完numpy/xxx/tests/test_yyy.py后,可以进入tests/目录并键入以下命令来运行测试:

代码语言:javascript复制
python test_yyy.py 

或者,如果将numpy/xxx/tests/添加到 Python 路径中,您可以在解释器中像这样运行测试:

代码语言:javascript复制
>>> import test_yyy
>>> test_yyy.test() 
__init__.pysetup.py

通常情况下,将tests/目录添加到 Python 路径中并不理想。相反,最好直接从模块xxx中调用测试。为此,在包的__init__.py文件的末尾添加以下几行即可:

代码语言:javascript复制
...
def test(level=1, verbosity=1):
    from numpy.testing import Tester
    return Tester().test(level, verbosity) 

您还需要在setup.py的配置部分中添加测试目录:

代码语言:javascript复制
...
def configuration(parent_package='', top_path=None):
    ...
    config.add_subpackage('tests')
    return config
... 

现在,您可以按照以下方式测试您的模块:

代码语言:javascript复制
>>> import numpy
>>> numpy.xxx.test() 

另外,当调用整个 NumPy 测试套件时,将找到并运行您的测试:

代码语言:javascript复制
>>> import numpy
>>> numpy.test()
# your tests are included and run automatically! 

小贴士和技巧

创建许多类似的测试

如果您有一组必须以微小变化多次运行的测试,可以创建一个包含所有常见测试的基类,然后为每个变体创建一个子类。NumPy 中存在多种此类技术的示例;以下是其中一个示例的摘录:numpy/linalg/tests/test_linalg.py。

代码语言:javascript复制
class LinalgTestCase:
    def test_single(self):
        a = array([[1., 2.], [3., 4.]], dtype=single)
        b = array([2., 1.], dtype=single)
        self.do(a, b)

    def test_double(self):
        a = array([[1., 2.], [3., 4.]], dtype=double)
        b = array([2., 1.], dtype=double)
        self.do(a, b)

    ...

class TestSolve(LinalgTestCase):
    def do(self, a, b):
        x = linalg.solve(a, b)
        assert_allclose(b, dot(a, x))
        assert imply(isinstance(b, matrix), isinstance(x, matrix))

class TestInv(LinalgTestCase):
    def do(self, a, b):
        a_inv = linalg.inv(a)
        assert_allclose(dot(a, a_inv), identity(asarray(a).shape[0]))
        assert imply(isinstance(a, matrix), isinstance(a_inv, matrix)) 

在这种情况下,我们希望使用几种数据类型的矩阵解决线性代数问题,使用linalg.solvelinalg.inv进行测试。常见的测试用例(例如单精度、双精度等矩阵)都收集在LinalgTestCase中。

已知的失败和跳过测试

有时,您可能希望跳过测试或将其标记为已知失败,例如在编写测试套件时在编写代码之前,或者如果测试仅在特定架构上失败。

要跳过测试,只需使用skipif

代码语言:javascript复制
import pytest

@pytest.mark.skipif(SkipMyTest, reason="Skipping this test because...")
def test_something(foo):
    ... 

如果SkipMyTest对非零进行评估,则测试将被标记为跳过,而详细测试输出中的消息将是skipif给出的第二个参数。类似地,可以使用xfail将测试标记为已知失败:

代码语言:javascript复制
import pytest

@pytest.mark.xfail(MyTestFails, reason="This test is known to fail because...")
def test_something_else(foo):
    ... 

当然,可以使用skipxfail无条件跳过测试或将其标记为已知失败,而无需参数。

在测试运行结束时,显示跳过测试和已知失败测试的总数。跳过的测试在测试结果中标记为'S'(或者对于verbose > 1,标记为'SKIPPED'),已知失败的测试标记为'x'(或者对于verbose > 1,标记为'XFAIL')。

随机数据的测试

随机数据上的测试是很好的,但是由于测试失败的目的是暴露新的 bug 或回归,一个大多数时间通过但偶尔会因为没有代码更改而失败的测试是没有帮助的。通过在生成之前设置随机数种子使随机数据可重现。可以使用 Python 的random.seed(some_number)或 NumPy 的numpy.random.seed(some_number),取决于随机数的来源。

或者,你可以使用Hypothesis生成任意数据。Hypothesis 为你管理 Python 和 Numpy 的随机种子,并提供一种非常简明而强大的方式来描述数据(包括hypothesis.extra.numpy,例如用于一组可互相广播的形状)。

在随机生成上的优势包括工具可以重播和共享失败而不需要固定种子,为每个失败报告最小的例子,以及为触发 bug 提供比朴素随机更好的技术。

numpy.test的文档
代码语言:javascript复制
numpy.test(label='fast', verbose=1, extra_argv=None, doctests=False, coverage=False, durations=-1, tests=None)

Pytest 测试运行器。

测试函数通常被添加到包的 init.py 中,如下所示:

代码语言:javascript复制
from numpy._pytesttester import PytestTester
test = PytestTester(__name__).test
del PytestTester 

调用此测试函数会找到并运行与模块及其所有子模块关联的所有测试。

参数:

module_namemodule name

要测试的模块的名称。

注释

与先前基于nose的实现不同,这个类并不是公开的,因为它执行了一些numpy特定的警告抑制。

属性:

module_namestr

要测试的包的完整路径。

创建许多类似的测试

如果你有一系列的测试需要多次运行,并且需要做一些小的变化,创建一个包含所有公共测试的基类,然后为每个变种创建一个子类是很有帮助的。NumPy 中存在这种技术的几个例子;下面摘录自numpy/linalg/tests/test_linalg.py:

代码语言:javascript复制
class LinalgTestCase:
    def test_single(self):
        a = array([[1., 2.], [3., 4.]], dtype=single)
        b = array([2., 1.], dtype=single)
        self.do(a, b)

    def test_double(self):
        a = array([[1., 2.], [3., 4.]], dtype=double)
        b = array([2., 1.], dtype=double)
        self.do(a, b)

    ...

class TestSolve(LinalgTestCase):
    def do(self, a, b):
        x = linalg.solve(a, b)
        assert_allclose(b, dot(a, x))
        assert imply(isinstance(b, matrix), isinstance(x, matrix))

class TestInv(LinalgTestCase):
    def do(self, a, b):
        a_inv = linalg.inv(a)
        assert_allclose(dot(a, a_inv), identity(asarray(a).shape[0]))
        assert imply(isinstance(a, matrix), isinstance(a_inv, matrix)) 

在这种情况下,我们想测试使用几种数据类型的矩阵来解决线性代数问题,使用linalg.solvelinalg.inv。通常的测试案例(单精度、双精度等矩阵)都被收集在LinalgTestCase中。

已知的失败与跳过的测试

有时你可能希望跳过一个测试或将其标记为已知的失败,比如在编写测试套件之前编写的代码,或者测试只在特定体系结构上失败。

要跳过一个测试,简单地使用skipif

代码语言:javascript复制
import pytest

@pytest.mark.skipif(SkipMyTest, reason="Skipping this test because...")
def test_something(foo):
    ... 

如果SkipMyTest评估为非零,则测试被标记为跳过,详细测试输出中的消息是skipif给定的第二个参数。同样,可以使用xfail将测试标记为已知失败:

代码语言:javascript复制
import pytest

@pytest.mark.xfail(MyTestFails, reason="This test is known to fail because...")
def test_something_else(foo):
    ... 

当然,也可以使用skipxfail无需参数无条件跳过测试或将其标记为已知的失败。

测试运行结束时显示跳过和已知失败测试的总数。跳过的测试在测试结果中标记为'S'(或verbose > 1时标记为'SKIPPED'),已知失败的测试标记为'x'(或verbose > 1时标记为'XFAIL')。

随机数据测试

随机数据测试虽然很好,但由于测试失败意味着暴露新的错误或回归,因此大部分时间通过但偶尔失败而没有代码更改的测试并不有用。通过在生成之前设置随机数种子来使随机数据具有确定性。根据随机数的来源使用 Python 的random.seed(some_number)或 NumPy 的numpy.random.seed(some_number)

或者,您可以使用Hypothesis生成任意数据。Hypothesis 为您管理 Python 和 Numpy 的随机种子,并提供了一种非常简洁而强大的描述数据的方法(包括hypothesis.extra.numpy,例如一组相互广播的形状)。

与随机生成相比的优点包括工具可以重放和分享失败而不需要固定的种子,为每个失败报告提供最小示例,并且触发错误的技术比朴素随机更好。

numpy.test的文档
代码语言:javascript复制
numpy.test(label='fast', verbose=1, extra_argv=None, doctests=False, coverage=False, durations=-1, tests=None)

Pytest 测试运行器。

测试函数通常像这样添加到包的 init.py 中:

代码语言:javascript复制
from numpy._pytesttester import PytestTester
test = PytestTester(__name__).test
del PytestTester 

调用此测试函数会查找并运行与模块及其所有子模块相关联的所有测试。

参数:

module_name模块名

要测试的模块的名称。

笔记

与之前基于nose的实现不同,这个类不会公开暴露,因为它执行了一些特定于numpy的警告抑制。

属性:

module_namestr

要测试的包的完整路径。

0 人点赞