NumPy 1.8.0 发行说明#
此版本支持 Python 2.6 - 2.7 和 3.2 - 3.3。
亮点#
新增,无需 2to3,Python 2 和 Python 3 由共同代码库支持。
新增,用于线性代数的 gufuncs,支持对堆叠数组进行操作。
新增,ufuncs 通过
.at
方法支持原地花式索引。新增,
partition
函数,通过选择进行部分排序以实现快速中位数计算。新增,
nanmean
、nanvar
和nanstd
函数,跳过 NaN 值。新增,
full
和full_like
函数,用于创建值初始化的数组。新增,
PyUFunc_RegisterLoopForDescr
,更好地支持用户 dtypes 的 ufunc。许多领域都有大量性能改进。
已取消支持#
已取消对 Python 2.4 和 2.5 版本的支持。
已移除对 SCons 的支持。
未来变更#
Datetime64 类型在此版本中仍处于实验阶段。在 1.9 版本中可能会有一些更改以使其更可用。
diagonal 方法当前返回一个新数组并引发 FutureWarning。在 1.9 版本中,它将返回一个只读视图。
从结构化类型数组中选择多个字段当前返回一个新数组并引发 FutureWarning。在 1.9 版本中,它将返回一个只读视图。
numpy/oldnumeric 和 numpy/numarray 兼容性模块将在 1.9 版本中移除。
兼容性说明#
doc/sphinxext 内容已移至其自己的 GitHub 仓库,并作为子模块包含在 numpy 中。有关如何访问该内容,请参阅 doc/HOWTO_BUILD_DOCS.rst 中的说明。
numpy.void 标量的哈希函数已更改。以前,指向数据的指针被哈希为一个整数。现在,哈希函数使用元组哈希算法组合标量元素的哈希函数,但仅当标量是只读时。
Numpy 已将其构建系统默认切换为使用“单独编译”。在以前的版本中,这受支持但不是默认设置。这应该会产生与旧系统相同的结果,但如果您尝试执行诸如静态链接 numpy 或使用不寻常的编译器等复杂操作,则可能会遇到问题。如果是这样,请提交错误报告,作为临时解决方案,您可以通过导出 shell 变量 NPY_SEPARATE_COMPILATION=0 来重新启用旧的构建系统。
对于 AdvancedNew 迭代器,oa_ndim
标志现在应为 -1,表示不传入 op_axes
和 itershape
。现在 oa_ndim == 0
的情况表示 0-D 迭代,并且 op_axes
为 NULL,旧用法已被弃用。这不影响 NpyIter_New
或 NpyIter_MultiNew
函数。
函数 nanargmin 和 nanargmax 现在对于全 NaN 切片中的索引返回 np.iinfo['intp'].min。以前,这些函数在数组返回时会引发 ValueError,在标量返回时会引发 NaN。
NPY_RELAXED_STRIDES_CHECKING#
有一个新的编译时环境变量 NPY_RELAXED_STRIDES_CHECKING
。如果此变量设置为 1,则 numpy 会将更多数组视为 C- 或 F-连续的——例如,现在可以拥有一个同时被视为 C- 和 F-连续的列向量。新定义更准确,允许更快地生成代码,减少不必要的复制,并简化 numpy 的内部代码。但是,它也可能会破坏对 C- 和 F-连续数组的步幅值做出过于强烈假设的第三方库。(目前已知这会破坏使用 memoryviews 的 Cython 代码,这将在 Cython 中修复。)这将在未来版本中成为默认设置,因此请立即针对使用以下方式构建的 NumPy 测试您的代码
NPY_RELAXED_STRIDES_CHECKING=1 python setup.py install
您可以通过运行以下命令检查 NPY_RELAXED_STRIDES_CHECKING 是否生效
np.ones((10, 1), order="C").flags.f_contiguous
如果启用了宽松步幅检查,这将为 True
,否则为 False
。到目前为止我们遇到的典型问题是处理 C-连续数组的 C 代码,并假设可以通过查看 PyArray_STRIDES(arr)
数组中的最后一个元素来访问 itemsize。当宽松步幅生效时,这不是真的(事实上,在某些边缘情况下它也从未是真的)。相反,请使用 PyArray_ITEMSIZE(arr)
。
有关更多信息,请查阅文档中的“ndarray 的内部内存布局”部分。
以非数组作为第二个参数的二进制操作#
形式为 <array-or-subclass> * <non-array-subclass>
的二进制操作,其中 <non-array-subclass>
声明的 __array_priority__
高于 <array-or-subclass>
的优先级,现在将无条件返回 NotImplemented,从而给 <non-array-subclass>
处理该操作的机会。以前,只有当 <non-array-subclass>
实际实现了反向操作,并且在尝试进行(可能很昂贵的)<non-array-subclass>
的数组转换之后,才会返回 NotImplemented。(错误,拉取请求)
与 overwrite_input 一起使用的 median 函数只部分排序数组#
如果 median 函数与 overwrite_input 选项一起使用,输入数组现在将只被部分排序,而不是完全排序。
修复 financial.npv#
npv 函数存在一个错误。与文档所述相反,它从索引 1
加总到 M
,而不是从 0
加总到 M - 1
。此修复更改了返回值。mirr 函数调用了 npv 函数,但绕过了该问题,因此也进行了修复,mirr 函数的返回值保持不变。
比较 NaN 数字时的运行时警告#
比较 NaN
浮点数现在会引发 invalid
运行时警告。如果预期出现 NaN
,可以使用 np.errstate 忽略该警告。例如:
with np.errstate(invalid='ignore'):
operation()
新功能#
支持堆叠数组上的线性代数#
gufunc 机制现在用于 np.linalg,允许对堆叠数组和向量进行操作。例如
>>> a
array([[[ 1., 1.],
[ 0., 1.]],
[[ 1., 1.],
[ 0., 1.]]])
>>> np.linalg.inv(a)
array([[[ 1., -1.],
[ 0., 1.]],
[[ 1., -1.],
[ 0., 1.]]])
ufuncs 的原地花式索引#
函数 at
已添加到 ufunc 对象中,允许在原地使用 ufunc,并且在使用花式索引时无需缓冲。例如,以下操作将递增数组中的第一个和第二个元素,并递增第三个元素两次:numpy.add.at(arr, [0, 1, 2, 2], 1)
这正是许多人错误地认为 arr[[0, 1, 2, 2]] += 1
会做的事情,但它不起作用,因为 arr[2]
的递增值只是被复制到 arr
的第三个槽位两次,而不是递增两次。
新函数 partition 和 argpartition#
通过选择算法部分排序数组的新函数。
按索引 k
进行的 partition
操作会将 k
个最小元素移动到数组的前面。然后,k
之前的所有元素都小于或等于位置 k
的值,而 k
之后的所有元素都大于或等于位置 k
的值。这些边界内的值顺序未定义。可以提供一个索引序列,通过迭代分区一次将所有这些索引排到其已排序的位置。这可以用于高效地获取样本的顺序统计量,例如中位数或百分位数。partition
的时间复杂度为线性 O(n)
,而完全排序的时间复杂度为 O(n log(n))
。
新函数 nanmean、nanvar 和 nanstd#
新增了支持 NaN 的统计函数。在这些函数中,结果是如果从所有计算中省略 NaN 值将获得的结果。
新函数 full 和 full_like#
新增了方便函数,用于创建填充特定值的数组;与现有的 zeros 和 zeros_like 函数互补。
与大型文件的 IO 兼容性#
在 64 位系统上可以加载大于 2GB 的大型 NPZ 文件。
针对 OpenBLAS 构建#
现在可以通过编辑 site.cfg 文件来针对 OpenBLAS 构建 numpy。
新常量#
欧拉常数现在在 numpy 中以 euler_gamma 的形式公开。
qr 的新模式#
qr 分解中新增了“complete”、“reduced”和“raw”模式,旧的“full”和“economic”模式已弃用。“reduced”模式替代了旧的“full”模式并成为默认模式,就像“full”模式一样,因此可以通过不指定模式来保持向后兼容性。
“complete”模式返回一个完整的维度分解,这对于获取范围空间的正交补基很有用。“raw”模式返回包含 Householder 反射器和缩放因子的数组,这些数组将来可用于应用 q 而无需转换为矩阵。“economic”模式已弃用,它没有太多用处,也比“raw”模式效率更高。
in1d 的新 invert 参数#
函数 in1d 现在接受一个 invert 参数,当其为 True 时,会导致返回的数组被反转。
使用 np.newaxis 进行高级索引#
现在可以使用 np.newaxis/None 与索引数组一起使用,而不仅仅是在简单索引中。这意味着 array[np.newaxis, [0, 1]]
现在将按预期工作,选择前两行,同时在数组前面添加一个新轴。
C-API#
现在可以使用内置输入类型和自定义输出类型注册新的 ufunc。在此更改之前,当从 Python 调用 ufunc 时,NumPy 无法找到正确的 ufunc 循环函数,因为 ufunc 循环签名匹配逻辑未查看输出操作数类型。现在可以找到正确的 ufunc 循环,只要用户提供具有正确输出类型的输出参数。
runtests.py#
添加了一个简单的测试运行脚本 runtests.py
。它还通过 setup.py build
构建 Numpy,并可用于在开发过程中轻松运行测试。
改进#
IO 性能改进#
通过分块(另请参阅 IO 兼容性)提高了读取大文件的性能。
pad 的性能改进#
pad 函数有了新的实现,极大提高了所有输入(除了 mode=,为保持向后兼容性而保留)的性能。维度为 4 或更高时,随维度变化的性能显著提高。
isnan, isinf, isfinite 和 byteswap 的性能改进#
isnan、isinf、isfinite 和 byteswap 已得到改进,可利用编译器内置函数来避免昂贵的 libc 调用。这使这些操作在 GNU libc 系统上的性能提高了大约两倍。
通过 SSE2 向量化提升性能#
已对多个函数进行优化,以利用 SSE2 CPU SIMD 指令。
- Float32 和 float64
基本数学运算(add, subtract, divide, multiply)
sqrt
minimum/maximum
absolute
- Bool
logical_or
logical_and
logical_not
这使得 float32/float64 的这些操作性能提高了高达 4 倍/2 倍,布尔值的性能提高了高达 10 倍,具体取决于数据在 CPU 缓存中的位置。原地操作的性能提升最大。
为了使用改进后的函数,必须在编译时启用 SSE2 指令集。在 x86_64 系统上,它默认启用。在具有兼容 CPU 的 x86_32 系统上,必须通过向 CFLAGS 构建变量传递适当的标志(使用 gcc 时为 -msse2)来启用它。
median 的性能改进#
median 现在通过 partition 而不是 sort 实现,将其时间复杂度从 O(n log(n)) 降低到 O(n)。如果与 overwrite_input 选项一起使用,数组现在将只被部分排序,而不是完全排序。
ufunc C-API 中可重写操作数标志#
创建 ufunc 时,可以通过 ufunc 对象的新 op_flags 属性覆盖默认的 ufunc 操作数标志。例如,要将第一个输入的 operand flag 设置为读/写:
PyObject *ufunc = PyUFunc_FromFuncAndData(…); ufunc->op_flags[0] = NPY_ITER_READWRITE;
这允许 ufunc 执行原地操作。此外,全局 nditer 标志可以通过 ufunc 对象的新 iter_flags 属性覆盖。例如,为 ufunc 设置 reduce 标志:
ufunc->iter_flags = NPY_ITER_REDUCE_OK;
变更#
通用#
函数 np.take 现在允许 0-d 数组作为索引。
单独编译模式现已默认启用。
np.insert 和 np.delete 的若干更改
以前,负索引和超出数组末尾的索引会被简单地忽略。现在,这会引发 Future 或 Deprecation Warning。将来,它们将像正常索引处理它们一样被处理——负索引将环绕,超出范围的索引将生成错误。
以前,布尔索引被视为整数(总是指向数组中的第 0 个或第 1 个元素)。将来,它们将被视为掩码。在此版本中,它们会引发 FutureWarning 警告此即将到来的更改。
在 Numpy 1.7 中,np.insert 已经允许使用语法 np.insert(arr, 3, [1,2,3]) 在单个位置插入多个项目。在 Numpy 1.8 中,np.insert(arr, [3], [1, 2, 3]) 也可以实现。
np.pad 填充区域现在已正确四舍五入,而不是截断。
C-API 数组新增#
数组 C-API 中新增了四个函数。
PyArray_Partition
PyArray_ArgPartition
PyArray_SelectkindConverter
PyDataMem_NEW_ZEROED
C-API Ufunc 新增#
ufunc C-API 中新增了一个函数,允许使用 descr 为用户类型注册内部循环。
PyUFunc_RegisterLoopForDescr
C-API 开发者改进#
PyArray_Type
实例创建函数 tp_new
现在使用 tp_basicsize
来确定分配多少内存。在以前的版本中,只分配了 sizeof(PyArrayObject)
字节的内存,这通常要求 C-API 子类型重新实现 tp_new
。
弃用#
qr 分解的“full”和“economic”模式已弃用。
通用#
已弃用对索引和大多数整数参数使用非整数值。以前,浮点索引和函数参数(例如轴或形状)会在不发出警告的情况下截断为整数。例如,arr.reshape(3., -1) 或 arr[0.] 将在 NumPy 1.8 中触发弃用警告,并且在 NumPy 的未来版本中将引发错误。