NumPy 1.15.0 版本说明#
NumPy 1.15.0 版本包含大量清理工作、许多旧函数的弃用以及对许多现有函数的改进。请阅读下面的详细说明,查看您是否受影响。
对于测试,我们已切换到 pytest,以替换不再维护的 nose 框架。旧的基于 nose 的接口仍然保留,供可能仍在使用它的下游项目使用。
此版本支持的 Python 版本为 2.7、3.4-3.7。轮子与 OpenBLAS v0.3.0 链接,这应该可以修复 NumPy 1.14 中报告的一些 linalg 问题。
亮点#
NumPy 已切换到 pytest 进行测试。
新的
numpy.printoptions
上下文管理器。对直方图函数的许多改进。
在 Python 2.7 中支持 Unicode 字段名称。
改进了对 PyPy 的支持。
对
numpy.einsum
的修复和改进。
新函数#
numpy.ma.stack
,numpy.stack
数组连接函数推广到掩码数组。numpy.quantile
函数,一个无需 100 系数的percentile
接口numpy.nanquantile
函数,一个无需 100 系数的nanpercentile
接口numpy.printoptions
,一个上下文管理器,可以临时设置打印选项,用于with
块的范围>>> with np.printoptions(precision=2): ... print(np.array([2.0]) / 3) [0.67]
numpy.histogram_bin_edges
,一个函数,用于获取直方图使用的箱的边缘,而无需计算直方图。已添加 C 函数 npy_get_floatstatus_barrier 和 npy_clear_floatstatus_barrier 来处理编译器优化更改操作顺序的情况。有关详细信息,请参见下文。
弃用#
内置
pickle
函数的别名已弃用,推荐使用未加别名的pickle.<func>
名称numpy.loads
numpy.core.numeric.load
numpy.core.numeric.loads
numpy.ma.loads,numpy.ma.dumps
numpy.ma.load,numpy.ma.dump - 这些函数在 Python 3 中使用字符串调用时已失败。
使用除元组之外的任何内容进行多维索引已被弃用。这意味着
ind = [slice(None), 0]; arr[ind]
中的索引列表应更改为元组,例如ind = [slice(None), 0]; arr[tuple(ind)]
或arr[(slice(None), 0)]
。此更改对于避免诸如arr[[[0, 1], [0, 1]]]
之类的表达式中的歧义是必要的,当前解释为arr[array([0, 1]), array([0, 1])]
,将来将解释为arr[array([[0, 1], [0, 1]])]
。以下子模块的导入已被弃用,它们将在未来的某个时间点被删除。
numpy.testing.utils
numpy.testing.decorators
numpy.testing.nosetester
numpy.testing.noseclasses
numpy.core.umath_tests
向
numpy.sum
提供生成器现在已被弃用。这是未记录的行为,但可以工作。以前,它会计算生成器表达式的总和。将来,它可能会返回不同的结果。请改用np.sum(np.from_iter(generator))
或内置的 Pythonsum
。C-API 的用户应在释放数组之前,对任何设置了
WRITEBACKIFCOPY
标志的数组调用PyArrayResolveWriteBackIfCopy
或PyArray_DiscardWritebackIfCopy
。如果在需要时未使用这些调用,则会发出弃用警告。nditer
的用户应在迭代器操作数之一可写时始终将 nditer 对象用作上下文管理器,以便 numpy 可以管理回写语义,或者应调用it.close()
。否则,在这些情况下可能会发出 RuntimeWarning。np.histogram
的normed
参数(很久以前在 1.6.0 中已弃用)现在会发出DeprecationWarning
。
未来的更改#
NumPy 1.16 将停止支持 Python 3.4。
NumPy 1.17 将停止支持 Python 2.7。
兼容性说明#
已重命名并设为私有的编译测试模块#
以下编译模块已重命名并设为私有
umath_tests
->_umath_tests
test_rational
->_rational_tests
multiarray_tests
->_multiarray_tests
struct_ufunc_test
->_struct_ufunc_tests
operand_flag_tests
->_operand_flag_tests
umath_tests
模块仍可用于向后兼容,但将在将来删除。
np.savez
返回的 NpzFile
现在是 collections.abc.Mapping
#
这意味着它的行为类似于只读字典,并具有新的 .values()
方法和 len()
实现。
对于 Python 3,这意味着 .iteritems()
、.iterkeys()
已被弃用,而 .keys()
和 .items()
现在返回视图而不是列表。这与 Python 2 和 Python 3 之间内置 dict
类型更改的方式一致。
在某些情况下,必须在上下文管理器中使用 nditer
#
当使用带有"writeonly"
或"readwrite"
标志的numpy.nditer
时,某些情况下,nditer实际上并不会提供可写数组的视图。相反,它会提供一个副本,如果您更改了副本,nditer稍后会将这些更改写回您的实际数组。目前,这种回写发生在数组对象被垃圾回收时,这使得该API在CPython上容易出错,在PyPy上完全失效。因此,当nditer
与可写数组一起使用时,现在应将其用作上下文管理器,例如with np.nditer(...) as it: ...
。对于上下文管理器不可用的情况,例如在生成器表达式中,您也可以显式调用it.close()
。
NumPy已切换到使用pytest进行测试,而不是nose#
nose的最后一个版本是2015年6月的1.3.7,该工具的开发已结束,因此NumPy现在已切换到使用pytest。某些下游项目以前使用的一些旧装饰器和nose工具仍然可用,但将不再维护。标准测试实用程序(例如assert_almost_equal
)不会受到此更改的影响,但nose特定函数import_nose
和raises
除外。这些函数在numpy中未使用,但为了下游兼容性而保留。
NumPy不再使用__array_interface__
修补ctypes
#
以前,numpy会将__array_interface__
属性添加到ctypes
中的所有整数类型。
np.ma.notmasked_contiguous
和np.ma.flatnotmasked_contiguous
始终返回列表#
这是文档化的行为,但以前结果可能是切片、None或列表中的任何一个。
所有下游用户似乎都在检查flatnotmasked_contiguous
返回的None
结果,并将其替换为[]
。这些调用者将继续像以前一样工作。
np.squeeze
恢复了无法处理axis
参数的对象的旧行为#
在1.7.0
版本之前,numpy.squeeze
没有axis
参数,并且默认情况下所有空轴都被移除。加入axis
参数使得可以选择性地压缩单个或多个空轴成为可能,但是旧的API期望没有得到遵守,因为仍然可以从期望删除所有空轴的对象中选择性地移除轴(静默成功)。针对期望旧行为的对象,这种静默选择性地移除空轴的问题已得到修复,并恢复了旧的行为。
非结构化void数组的.item
方法现在返回一个bytes对象#
.item
现在返回一个bytes
对象,而不是缓冲区或字节数组。这可能会影响假设返回值是可变的代码,这种情况现在不再存在。
copy.copy
和copy.deepcopy
不再将masked
转换为数组#
由于np.ma.masked
是只读标量,因此复制应该是一个无操作。这些函数现在与np.copy()
的行为一致。
结构化数组的多字段索引仍将返回副本#
结构化数组的多字段索引返回视图而不是副本的更改已推迟到1.16版本。为了帮助减轻此更改的影响,引入了一种新方法numpy.lib.recfunctions.repack_fields
,该方法可用于编写与numpy 1.15和1.16都兼容的代码。有关如何更新代码以适应此未来更改的更多信息,请参阅用户指南中的“访问多个字段”部分。
C API更改#
新增函数npy_get_floatstatus_barrier
和npy_clear_floatstatus_barrier
#
已添加函数npy_get_floatstatus_barrier
和npy_clear_floatstatus_barrier
,应将其用于代替npy_get_floatstatus
和npy_clear_status
函数。当在ufunc SIMD函数中使用以前的函数时,像GCC 8.1和Clang这样的优化编译器会重新排列操作顺序,导致在运行我们想要检查其状态的操作之前检查floatstatus标志。参见#10339。
对PyArray_GetDTypeTransferFunction
的更改#
PyArray_GetDTypeTransferFunction
现在默认情况下使用用户定义的copyswapn
/copyswap
来处理用户定义的dtype。如果这会导致严重的性能下降,请考虑实现copyswapn
以反映PyArray_GetStridedCopyFn
的实现。参见#10898。
新功能#
为整数和对象类型添加了np.gcd
和np.lcm
ufunc#
这些分别计算最大公约数和最小公倍数。它们适用于所有numpy整数类型,以及内置的任意精度Decimal
和long
类型。
支持iOS的跨平台构建#
构建系统已修改为添加对_PYTHON_HOST_PLATFORM
环境变量的支持,该变量在跨平台编译时由distutils
使用。这使得可以为iOS目标编译NumPy。
这仅允许您一次为一个特定平台编译NumPy。创建完全兼容iOS的NumPy包需要为iOS支持的5种架构(i386、x86_64、armv7、armv7s和arm64)进行构建,并将这5个编译后的构建产品组合成单个“fat”二进制文件。
为np.intersect1d
添加了return_indices
关键字#
新的关键字return_indices
返回对应于公共元素的两个输入数组的索引。
np.quantile
和np.nanquantile
#
类似于np.percentile
和np.nanpercentile
,但是采用[0, 1]范围内的分位数而不是[0, 100]范围内的百分位数。np.percentile
现在是np.quantile
的薄包装器,多了一个除以100的步骤。
构建系统#
添加了对64位RISC-V架构的实验性支持。
改进#
np.einsum
更新#
同步numpy
和opt_einsum之间的einsum路径优化技术。特别是,greedy路径已由@jcmgray进行了许多增强。已修复问题的完整列表如下:
可以将任意内存传递到greedy路径中。修复了gh-11210。
greedy路径已更新为包含更多动态规划思想,避免了大量重复(且代价高昂)的调用,这些调用计算实际发生的配对收缩。现在在数百个输入张量上只需几秒钟即可完成。对于矩阵产品状态理论很有用。
重新设计了在gh-11218 gh-10352中发现的广播点错误捕获,使其在流程中更早一些。
增强了can_dot功能,该功能以前错过了一个边缘情况(gh-11308的一部分)。
np.flip
可以跨多个轴操作#
np.flip
现在在其axis
参数中接受None或整数元组。如果axis为None,它将翻转所有轴。
histogram
和 histogramdd
函数已移动到 np.lib.histograms
#
这些函数最初位于 np.lib.function_base
中。它们仍然可以通过未限定的名称 np.histogram(dd)
使用,并且为了保持兼容性,还在 np.lib.function_base.histogram(dd)
处创建了别名。
使用 from np.lib.function_base import *
的代码需要更新为新的位置,并且应该考虑在将来避免使用 import *
。
当给出显式 bin 时,histogram
将接受 NaN 值#
之前,在尝试计算数据的有限范围时会失败。由于当显式给出 bin 时范围会被忽略,因此此错误是多余的。
请注意,对 NaN 值调用 histogram
将继续引发处理 nan 值时常见的 RuntimeWarning
,这可以使用 errstate
像往常一样消除。
当给出显式 bin 边界时,histogram
可用于 datetime 类型#
现在可以对日期、时间和时间差进行直方图统计。必须显式传递 bin 边界,目前尚不能自动计算。
histogram
的“auto”估计器更好地处理有限方差#
IQR 为 0 不会再导致 n_bins=1
,在这种情况下,选择的 bin 数量与数据大小相关。
histogram
和 histogramdd
返回的边界现在与数据浮点类型匹配#
当传递 np.float16
、np.float32
或 np.longdouble
数据时,返回的边界现在具有相同的 dtype。之前,只有在给出显式 bin 时,histogram
才会返回相同的类型,而无论输入是什么,histogram
都会产生 float64
bin。
histogramdd
允许在部分轴上给出显式范围#
numpy.histogramdd
的 range
参数现在可以包含 None
值,表示应根据数据计算相应轴的范围。以前,这无法按轴进行指定。
histogramdd
和 histogram2d
的 normed
参数已重命名#
这些参数现在称为 density
,这与 histogram
保持一致。旧参数仍然有效,但应优先使用新名称。
np.r_
可用于 0d 数组,np.ma.mr_
可用于 np.ma.masked
#
现在,传递给 r_
和 mr_
连接帮助器的 0d 数组被视为长度为 1 的数组。以前,传递这些数组会出错。因此,numpy.ma.mr_
现在可以正确处理 masked
常量。
np.ptp
接受 keepdims
参数并扩展轴元组#
np.ptp
(峰峰值)现在可以像 np.max
和 np.min
一样在多个轴上工作。
MaskedArray.astype
现在与 ndarray.astype
相同#
这意味着它接受所有相同的参数,使得为 ndarray 编写的更多代码也可以用于掩码数组。
在编译时启用 AVX2/AVX512#
更改 simd.inc.src 以允许在编译时使用 AVX2 或 AVX512。以前,即使其余代码使用了 AVX2,使用 -march=native 编译 avx2(或 512)仍然会为 simd 函数使用 SSE 代码。
nan_to_num
在接收标量或 0d 输入时始终返回标量#
以前,对于整数标量输入会返回一个数组,这与浮点输入的行为以及 ufunc 的一般行为不一致。对于所有类型的标量或 0d 输入,结果现在都是标量。
np.flatnonzero
可用于可转换为 numpy 的类型#
np.flatnonzero
现在使用 np.ravel(a)
代替 a.ravel()
,因此它可以用于列表、元组等。
np.interp
返回 numpy 标量而不是内置标量#
以前 np.interp(0.5, [0, 1], [10, 20])
会返回一个 float
,但现在它返回一个 np.float64
对象,这更接近其他函数的行为。
此外,不再支持 np.interp(object_array_0d, ...)
的特殊情况,因为无论如何都不支持 np.interp(object_array_nd)
。
由于此更改,现在可以在 0d 数组上使用 period
参数。
允许在 Python 2 中使用 Unicode 作为 dtype 字段名#
以前,在 Python 2 中,np.dtype([(u'name', float)])
会引发 TypeError
,因为字段名只允许使用字节字符串。现在,任何 Unicode 字符串字段名都将使用 ascii
编码器进行编码,并在失败时引发 UnicodeEncodeError
。
此更改使使用 from __future__ import unicode_literals
编写 Python 2/3 兼容代码更容易,这在以前会导致字符串字面量字段名在 Python 2 中引发 TypeError。
比较 ufunc 接受 dtype=object
,覆盖默认的 bool
#
这允许包含符号类型的对象数组(覆盖 ==
和其他运算符以返回表达式)使用 np.equal(a, b, dtype=object)
进行逐元素比较。
sort
函数接受 kind='stable'
#
到目前为止,要对数据进行稳定排序,用户必须执行以下操作:
>>> np.sort([5, 2, 6, 2, 1], kind='mergesort')
[1, 2, 2, 5, 6]
因为合并排序是 NumPy 中唯一可用的稳定排序算法。但是,使用 kind='mergesort' 并不能明确表明用户想要执行稳定排序,从而影响可读性。
此更改允许用户指定 kind='stable',从而明确其意图。
对于就地累加,不要创建临时副本#
当 ufunc 执行累加时,由于输入和输出之间的重叠,它们不再创建临时副本,也就是说,在累加结果存储到位之前,会添加下一个累加的元素,因此重叠是安全的。避免复制可以加快执行速度。
linalg.matrix_power
现在可以处理矩阵堆栈#
与linalg
中的其他函数一样,matrix_power
现在可以处理维度大于2的数组,这些数组被视为矩阵堆栈。作为更改的一部分,为了进一步提高一致性,第一个参数的名称已更改为a
(从M
),非方阵的异常已更改为LinAlgError
(从ValueError
)。
提高了random.permutation
中多维数组的性能#
permutation
对所有输入数组维度都使用random.shuffle
中的快速路径。以前,快速路径仅用于一维数组。
广义ufunc现在接受axes
、axis
和keepdims
参数#
可以通过传递axes
参数(包含特定轴索引的元组列表)来控制广义ufunc作用的轴。例如,对于矩阵乘法合适的签名(i,j),(j,k)->(i,k)
,基元素是二维矩阵,这些矩阵存储在每个参数的最后两个轴中。相应的axes关键字将是[(-2, -1), (-2, -1), (-2, -1)]
。如果要使用前导维度,则应传入[(0, 1), (0, 1), (0, 1)]
。
为简便起见,对于作用于一维数组(向量)的广义ufunc,接受单个整数而不是单个元素的元组;对于所有输出都是标量的广义ufunc,可以省略(空)输出元组。因此,对于内积合适的签名(i),(i)->()
,可以传入axes=[0, 0]
来指示向量存储在两个输入参数的第一个维度中。
作为快捷方式,对于类似于归约的广义ufunc(例如上面的内积示例),即作用于单个共享核心维度,可以使用axis
参数。这等效于使用具有相同条目的axes
传递所有具有该核心维度的参数(例如,对于上面的示例,axes=[(axis,), (axis,)]
)。
此外,与归约类似,对于所有输入具有相同数量的核心维度且输出没有核心维度的广义ufunc,可以传入keepdims
以在输出中保留大小为1的维度,从而允许针对原始输入进行正确的广播。可以使用axes
控制额外维度的位置。例如,对于内积示例,keepdims=True, axes=[-2, -2, -2]
将作用于内积示例,keepdims=True, axis=-2
将作用于输入参数的倒数第二个维度,并在输出的相应位置保留大小为1的维度。
float128值现在可以在ppc系统上正确打印#
以前,由于这些系统上的特殊双精度浮点格式未被考虑在内,因此在ppc上打印float128值存在错误。float128现在以正确的舍入和唯一性打印。
对ppc用户的警告:如果glibc版本<=2.23,则应升级glibc,尤其是在使用float128时。在ppc上,这些版本的glibc的malloc经常会错误地对齐分配的内存,这在使用float128值时可能会导致numpy崩溃。
新增np.take_along_axis
和np.put_along_axis
函数#
当用于多维数组时,argsort
、argmin
、argmax
和argpartition
返回难以用作索引的数组。take_along_axis
提供了一种简单的方法来使用这些索引查找数组中的值,因此
np.take_along_axis(a, np.argsort(a, axis=axis), axis=axis)
与
np.sort(a, axis=axis)
np.put_along_axis
作为写入数组中这些索引的双重操作。