numpy 1.14.0是七个月工作的结果,包含大量的错误修复和新功能,以及一些可能存在兼容性问题的更改。用户将注意到的主要变化是numpy数组和scalar的打印方式的样式变化,这将影响doctest。有关如何在需要时保留旧样式打印的详细信息,请参见下文。
影响未来开发的一个重大决策涉及到到在2020年之前放弃对python 2.7的支持的计划。已决定支持2018年发布的所有版本的2.7版本,最后一个版本被指定为长期版本,并支持扩展到2019年的bug修复。2019年,对2.7的支持将在所有新版本中取消。有关更多详细信息,请参见 NEP 12 .
这个版本支持python 2.7和3.4-3.6。
这个 np.einsum 函数尽可能使用blas
genfromtxt , loadtxt , fromregex 和 savetxt 现在可以使用支持python的任意编码处理文件。
genfromtxt
loadtxt
fromregex
savetxt
numpy数组和scalar打印的主要改进。
parametrize :添加到numpy.testing的decorator
parametrize
chebinterpolate :在切比雪夫点插入函数。
chebinterpolate
format_float_positional 和 format_float_scientific :使用舍入和填充控件明确设置浮点标量的格式。
format_float_positional
format_float_scientific
PyArray_ResolveWritebackIfCopy 和 PyArray_SetWritebackIfCopyBase ,新的C-API函数有助于实现PyPy兼容性。
PyArray_ResolveWritebackIfCopy
PyArray_SetWritebackIfCopyBase
使用 np.bool_ 不推荐使用对象代替整数。以前 operator.index(np.bool_) 是合法的并且允许构造,例如 [1, 2, 3][np.True_] . 这是误导,因为它的行为与 np.array([1, 2, 3])[np.True_] .
np.bool_
operator.index(np.bool_)
[1, 2, 3][np.True_]
np.array([1, 2, 3])[np.True_]
空数组的真值测试已弃用。要检查数组是否不为空,请使用 array.size > 0 .
array.size > 0
调用 np.bincount 具有 minlength=None 被贬低。 minlength=0 应该改为使用。
np.bincount
minlength=None
minlength=0
调用 np.fromstring 默认值为 sep 参数已弃用。如果未提供该参数,则为 np.frombuffer 它静默地接受unicode字符串,在将其编码为utf-8(python 3)或默认编码(python 2)之后,将其视为二进制数据。如果需要读取二进制数据, np.frombuffer 应直接使用。
np.fromstring
sep
np.frombuffer
这个 style 在非传统打印模式中,不推荐使用array2string选项。
style
PyArray_SetUpdateIfCopyBase 已弃用。对于numpy版本>=1.14,使用 PyArray_SetWritebackIfCopyBase 相反,看到 C API changes 详情请参见下文。
PyArray_SetUpdateIfCopyBase
UPDATEIFCOPY 数组已弃用,请参见 C API changes 详情见下文。我们不会放弃对这些数组的支持,但它们与Pypy不兼容。
UPDATEIFCOPY
np.issubdtype 将停止向下转换类似于数据类型的参数。可以预料到 issubdtype(np.float32, 'float64') 和 issubdtype(np.float32, np.float64) 意思是一样的-然而,有一个未经记录的特殊案例将前者转化为 issubdtype(np.float32, np.floating) 给出了令人惊讶的结果。
np.issubdtype
issubdtype(np.float32, 'float64')
issubdtype(np.float32, np.float64)
issubdtype(np.float32, np.floating)
这个翻译现在给出了一个警告,解释了正在发生的翻译。将来,翻译将被禁用,第一个示例将与第二个示例等效。
np.linalg.lstsq 默认为 rcond 将被更改。这个 rcond 参数到 np.linalg.lstsq 将其默认值更改为机器精度乘以输入数组的最大尺寸。在以下情况下发出未来警告: rcond 未显式传递。
np.linalg.lstsq
rcond
a.flat.__array__() 将返回的可写副本 a 什么时候? a 不连续。以前,当 a 是可写的。当前它返回一个不可写副本。关于该问题的讨论见GH-7054。
a.flat.__array__()
a
非结构化void数组 .item 方法将返回一个bytes对象。在未来,打电话给 .item() 在数组或标量上 np.void 数据类型将返回 bytes 对象,而不是缓冲区或int数组,与返回的相同 bytes(void_scalar) . 这可能会影响假定返回值是可变的代码,这种情况将不再如此。一 FutureWarning 在可能发生这种情况时发出。
.item
.item()
np.void
bytes
bytes(void_scalar)
FutureWarning
在numpy 1.11.x中有一个关于此更改的未来警告。简言之,现在的情况是,更改遮罩数组的视图时,对遮罩的更改将传播到原始遮罩。以前不是这样的。此更改尤其影响切片。请注意,如果原始数组的掩码是 nomask 视图的遮罩也会改变。请参阅GH-5580进行扩展讨论。通过调用 unshare_mask 视图的方法。
nomask
unshare_mask
np.ma.masked
尝试改变 masked 常量现在出错,因为基础数组被标记为只读。在过去,我们可以摆脱:
masked
# emulating a function that sometimes returns np.ma.masked val = random.choice([np.ma.masked, 10]) var_arr = np.asarray(val) val_arr += 1 # now errors, previously changed np.ma.masked.data
np.ma
fill_value
以前, np.ma.default_fill_value 将返回0d数组,但 np.ma.minimum_fill_value 和 np.ma.maximum_fill_value 将返回字段的元组。相反,这三个方法都返回结构化的 np.void 对象,这是您在 .fill_value 属性。
np.ma.default_fill_value
np.ma.minimum_fill_value
np.ma.maximum_fill_value
.fill_value
此外,现在的数据类型猜测与 np.array -所以当传递python标量时 x , maximum_fill_value(x) 总是和 maximum_fill_value(np.array(x)) . 以前 x = long(1) 在Python2上违反了这个假设。
np.array
x
maximum_fill_value(x)
maximum_fill_value(np.array(x))
x = long(1)
其目的是,当 a WAS非连续将在将来被可写副本替换。此临时措施旨在通知希望在这种情况下修改基础数组的人员,情况将不再如此。最有可能引起注意的地方是 np.asarray(a.flat) 使用,或何时使用 a.flat 作为out参数传递给ufunc。
np.asarray(a.flat)
a.flat
np.tensordot
以前 np.tensordot 收缩长度超过0的维度时引发值错误。现在它返回一个零数组,这与 np.dot 和 np.einsum .
np.dot
np.einsum
numpy.testing
预计这不会造成问题,但可能遗漏了一些内容。如果遇到意外的导入问题,请使用 numpy.testing 让我们知道。
np.asfarray
dtype
这以前会接受 dtype=some_array ,其隐含语义为 dtype=some_array.dtype . 这是未记录的,在numpy函数中是唯一的,如果使用的话,可能对应于一个打字错误。
dtype=some_array
dtype=some_array.dtype
np.linalg.norm
以前,这将促进 float64 当任意命令通过时,尽管在简单情况下没有这样做:
float64
>>> f32 = np.float32([[1, 2]]) >>> np.linalg.norm(f32, 2.0, axis=-1).dtype dtype('float32') >>> np.linalg.norm(f32, 2.0001, axis=-1).dtype dtype('float64') # numpy 1.13 dtype('float32') # numpy 1.14
此更改仅影响 float32 和 float16 数组。
float32
float16
count_nonzero(arr, axis=())
在别处, axis==() 总是被理解为“没有轴”,但是 count_nonzero 有一个特殊的案例把它当作“所有轴”。这是不一致和令人惊讶的。计算所有轴的正确方法始终是通过 axis == None .
axis==()
axis == None
__init__.py
这是为了在不同目录中存在重复测试文件名的情况下实现pytest兼容性。因此, run_module_suite 不再有效,即, python <path-to-test-file> 导致错误。
run_module_suite
python <path-to-test-file>
.astype(bool)
bool
在Python 2上, void_array.astype(bool) 将始终返回 True ,除非数据类型为 V0 . 在Python3上,此操作通常会崩溃。往前走, astype 匹配的行为 bool(np.void) ,将所有零的缓冲区视为假,而将其他任何值视为真。检查 V0 仍然可以用 arr.dtype.itemsize == 0 .
void_array.astype(bool)
True
V0
bool(np.void)
arr.dtype.itemsize == 0
MaskedArray.squeeze
np.squeeze 被记录为返回视图,但被屏蔽的变量有时会返回 masked ,这不是视图。这已被修复,因此结果始终是原始屏蔽数组上的视图。这会破坏所有使用的代码 masked_arr.squeeze() is np.ma.masked ,但修复了写入结果的代码 squeeze() .
np.squeeze
masked_arr.squeeze() is np.ma.masked
can_cast
from
from_
上一个参数名 from 是python中的保留关键字,这使按名称传递参数变得困难。已通过将参数重命名为来修复此问题。 from_ .
isnat
TypeError
UFUNC isnat 用来养一个 ValueError 当没有传递类型的变量时 datetime 或 timedelta . 这已改为提高 TypeError .
ValueError
datetime
timedelta
dtype.__getitem__
当使用浮点进行索引时,用于提升 ValueError .
__str__
__repr__
以前,用户定义的类型可以返回到 __str__ 和 __repr__ 在numpy中实现,但现在已移除。现在,用户定义的类型将返回到python默认值。 object.__str__ 和 object.__repr__ .
object.__str__
object.__repr__
这个 str 和 repr 在ndarrays和numpy scalars中,有多种方式被改变。这些更改可能会破坏下游用户的条令。
str
repr
通过启用新的1.13“旧版”打印模式,可以禁用这些新行为,以主要复制numpy 1.13行为。这是通过调用 np.set_printoptions(legacy="1.13") 或使用新的 legacy 参数 np.array2string 作为 np.array2string(arr, legacy='1.13') .
np.set_printoptions(legacy="1.13")
legacy
np.array2string
np.array2string(arr, legacy='1.13')
总之,主要变化是:
对于浮点类型:
这个 repr 浮点数数组中,通常省略以前在符号位置打印的空格。看到新的 sign 选择权 np.set_printoptions .
sign
np.set_printoptions
浮点数组和标量使用新的十进制表示算法,给出最短的唯一表示。这通常会缩短 float16 分数输出,有时 float32 和 float128 输出。 float64 应该不受影响。看到新的 floatmode 选择权 np.set_printoptions .
float128
floatmode
以科学记数法打印的浮点数组不再使用固定精度,而是显示最短的唯一表示。
这个 str 在python2中,浮点标量不再被截断。
对于其他数据类型:
非有限复标量类打印 nanj 而不是 nan*j .
nanj
nan*j
NaT 日期时间数组中的值现在已正确对齐。
NaT
数组和标量 np.void 数据类型现在使用十六进制表示法打印。
对于换行:
如果数组输出的最后一行上没有空间,则现在将在下一行打印ndarray reprs的“dtype”部分。
这个 linewidth 格式选项现在总是得到遵守。这个 repr 或 str 除非单个元素太宽,否则数组的值永远不会超过此值。
linewidth
数组字符串的最后一行的元素永远不会比前面的行多。
如果元素太宽,将不再在第一行插入额外的空间。
用于总结(使用 ... 要缩短长数组,请执行以下操作:
...
不再为插入尾随逗号 str . 以前, str(np.arange(1001)) 给 '[ 0 1 2 ..., 998 999 1000]' ,它有一个额外的逗号。
str(np.arange(1001))
'[ 0 1 2 ..., 998 999 1000]'
对于二维及以上的数组,当 ... 为了总结除最后一个轴以外的任何轴,现在将换行附加到该行以匹配其前导换行,并删除尾随空格字符。
MaskedArray 数组现在用逗号分隔打印的元素,始终打印数据类型,并将长数组的元素正确包装为多行。如果有超过1个维度,则数组属性现在以新的“左对齐”打印样式打印。
MaskedArray
recarray 数组在其数据类型之前不再打印尾随空格,而是换行到正确的列数。
recarray
0d数组不再有自己的特殊实现 str 和 repr . 这个 style 参数 np.array2string 被贬低。
数组 bool 数据类型将省略 repr .
用户定义的 dtypes (子类) np.generic )现在需要实施 __str__ 和 __repr__ .
dtypes
np.generic
下面将更详细地描述其中的一些更改。如果出于教义或其他原因需要保留以前的行为,您可能需要执行以下操作:
# FIXME: We need the str/repr formatting used in Numpy < 1.14. try: np.set_printoptions(legacy='1.13') except TypeError: pass
UPDATEIFCOPY 数组是现有数组的连续副本,可能具有不同的维度,当其refcount变为零并且释放时,这些数组的内容将被复制回原始数组。因为pypy不使用refcounts,所以它们不能与pypy一起正常工作。numpy正在取消内部使用和两个新的C-API函数,
PyArray_ResolveWritebackIfCopy,
加上免费的国旗, NPY_ARRAY_WRITEBACKIFCOPY . 使用新功能还需要在创建新数组时更改一些标志,即: NPY_ARRAY_INOUT_ARRAY 应替换为 NPY_ARRAY_INOUT_ARRAY2 和 NPY_ARRAY_INOUT_FARRAY 应替换为 NPY_ARRAY_INOUT_FARRAY2 . 使用这些新标志创建的数组将具有 WRITEBACKIFCOPY 语义学。
NPY_ARRAY_WRITEBACKIFCOPY
NPY_ARRAY_INOUT_ARRAY
NPY_ARRAY_INOUT_ARRAY2
NPY_ARRAY_INOUT_FARRAY
NPY_ARRAY_INOUT_FARRAY2
WRITEBACKIFCOPY
如果Pypy兼容性不是问题,那么可以忽略这些新函数,尽管 DeprecationWarning . 如果您确实希望实现Pypy兼容性,可以在 c-api 文档和中的示例 how-to-extend.
DeprecationWarning
genfromtxt , loadtxt , fromregex 和 savetxt 现在可以通过encoding参数处理具有python支持的任意编码的文件。为了向后兼容,参数默认为 bytes 值,该值继续将文本视为原始字节值,并继续将Latin1编码的字节传递给自定义转换器。使用任何其他值(包括 None 对于系统默认值),将把函数切换为实文本IO,这样就可以接收到Unicode字符串,而不是结果数组中的字节。
None
nose
numpy.testing.Tester
numpy.testing.Tester 现在意识到 nose 位于外部的插件 nose 内置的。这允许使用,例如, nose-timer 像这样: np.test(extra_argv=['--with-timer', '--timer-top-n', '20']) 以获取20个最慢测试的运行时。一个额外的关键字 timer 也被添加到 Tester.test 如此 np.test(timer=20) 还将报告20个最慢的测试。
nose-timer
np.test(extra_argv=['--with-timer', '--timer-top-n', '20'])
timer
Tester.test
np.test(timer=20)
基本的 parametrize 装饰现在可在 numpy.testing . 它的目的是允许重写Pytest中已弃用的基于收益的测试,以便于将来转换到Pytest。鼻子测试框架已经有好几年没有得到支持了,看起来像是废弃软件。
新的 parametrize decorator没有pytest中的decorator的全部功能。它不适用于类,不支持嵌套,也不替换变量名。即使如此,它也应该足以重写 NumPy 测试。
numpy.polynomial.chebyshev
新的 chebinterpolate 函数在第一类切比雪夫点内插给定函数。一个新的 Chebyshev.interpolate 类方法使用第一类缩放和移动的切比雪夫点在任意间隔上添加对插值的支持。
Chebyshev.interpolate
使用包含 lzma 模块文本IO功能现在可以透明地从文件中读取 xz 或 lzma 延伸。
lzma
xz
np.setprintoptions
此选项控制浮点类型符号的打印,可以是字符“-”、“+”或“”之一。使用“+”numpy总是打印正值的符号,使用“”它总是在正值的符号位置打印一个空格(空白字符),使用“-”它将省略正值的符号字符。新的默认值是“-”。
这个新的默认值改变了相对于numpy 1.13的浮点输出。旧行为可以在1.13“传统”打印模式下获得,请参见上面的兼容性说明。
hermitian
新的 hermitian 选项允许在基于标准SVD的矩阵秩计算和更有效的基于特征值的对称/厄米特矩阵方法之间进行选择。
threshold
edgeitems
这些选项以前可以使用 np.set_printoptions ,但现在可以根据每个调用更改为 np.array2string .
concatenate
stack
out
所需数据类型的预分配缓冲区现在可用于这些函数的输出。
PGI Flang编译器是Nvidia根据Apache2许可证发布的LLVM的Fortran前端。它可以通过以下方式调用:
python setup.py config --compiler=clang --fcompiler=flang install
使用这种新编译器的经验很少,因此使用它的人的任何反馈都会受到赞赏。
random.noncentral_f
在numpy 1.14.0之前,分子的自由度需要大于1,但是对于值大于0的分布是有效的,这是新的要求。
某些具有加速循环版本的特定循环结构在numpy 1.14.0之前没有释放gil。这一监督已得到纠正。
这个 np.einsum 函数现在将调用 np.tensordot 在适当的时候。因为 np.tensordot 尽可能使用blas,这将加快执行速度。默认情况下, np.einsum 还将尝试优化,因为相对于速度的潜在改进,开销很小。
f2py
f2py 现在允许分配维度0的数组。这样可以更一致地处理下游的角箱。
numpy.distutils
numpy distutils现在支持同时使用mingw64 gfortran和msvc编译器。这样就可以在包含Fortran代码的Windows上生成python扩展模块,同时保持与python.org分发的二进制文件的兼容性。并非所有的用例都受支持,但最常见的为Python包装Fortran的方法是功能性的。
此模式下的编译通常是自动启用的,可以通过 --fcompiler 和 --compiler 选项到 setup.py . 此外,支持将Fortran代码链接到静态openblas;默认情况下,支持gfortran兼容的静态存档 openblas.a 是寻找的。
--fcompiler
--compiler
setup.py
openblas.a
np.linalg.pinv
以前它仅限于单个二维阵列。
numpy.save
在中保存numpy数组 npy 格式与 numpy.save 在数组数据前插入填充,以64字节对齐。以前这只是16个字节(有时由于版本2的代码中的错误而减少)。现在对齐为64字节,这与最宽的SIMD指令集(通常可用)相匹配,也是最常见的缓存线大小。这使得 npy 在用打开文件的程序中更容易使用的文件 mmap 尤其是在Linux上, mmap 偏移量必须是页面大小的倍数。
npy
mmap
在Python 3.6 +中 numpy.savez 和 numpy.savez_compressed 现在直接写入zip文件,而不创建中间临时文件。
numpy.savez
numpy.savez_compressed
结构化类型可以包含零个字段,字符串数据类型可以包含零个字符。仍然无法直接创建零长度字符串,必须通过结构化DTypes:构造:
str0 = np.empty(10, np.dtype([('v', str, N)]))['v'] void0 = np.empty(10, np.void)
始终可以使用这些阵列,但这些阵列现在支持以下操作:
arr.sort() arr.view(bytes) arr.resize(...) pickle.dumps(arr)
arr.sort()
arr.view(bytes)
arr.resize(...)
pickle.dumps(arr)
decimal.Decimal
np.lib.financial
除非另有说明,否则 financial 包现在支持使用 decimal.Decimal 内置类型。
financial
这个 str 和 repr 其中的浮点值(16位、32位、64位和128位)现在被打印出来,以给出最短的十进制表示,它唯一地从同一类型的其他值中标识该值。以前这只适用于 float64 价值观。剩余的浮点类型现在通常比numpy 1.13中的要短。以科学记数法打印的数组现在也使用最短的科学表示,而不像以前那样使用固定精度。
另外, str 与python2不同,float scalars的scalars在python2中不再被截断。 float S. np.double scalars现在有一个 str 和 repr 与 Python 3漂浮物相同。
新功能 np.format_float_scientific 和 np.format_float_positional 用于生成这些十进制表示。
np.format_float_scientific
np.format_float_positional
一种新的选择 floatmode 已添加到 np.set_printoptions 和 np.array2string 从而控制数组中打印元素的唯一性和舍入。新的默认值是 floatmode='maxprec' 具有 precision=8 ,最多可以打印8个小数位数,如果一个元素可以用更少的小数唯一表示,则可以打印更少的小数位数。一个有用的新模式是 floatmode="unique" ,它将输出足够的数字以唯一地指定数组元素。
floatmode='maxprec'
precision=8
floatmode="unique"
nummy复杂的浮点标量,值如下 inf*j 或 nan*j 现在打印为 infj 和 nanj 就像纯 Python complex 类型。
inf*j
infj
complex
这个 FloatFormat 和 LongFloatFormat 类已弃用,应同时替换为 FloatingFormat . 同样地 ComplexFormat 和 LongComplexFormat 应替换为 ComplexFloatingFormat .
FloatFormat
LongFloatFormat
FloatingFormat
ComplexFormat
LongComplexFormat
ComplexFloatingFormat
void
与python兼容的十六进制表示法 bytes 类型现在打印为非结构化 np.void 元素,例如 V4 数据类型。以前,在python2中,元素的原始无效数据被打印到stdout,或者在python3中,显示整数字节值。
V4
印刷风格 np.void 现在可以使用 formatter 参数 np.set_printoptions ,使用 'void' 键,而不是全部捕获 numpystr 关键依旧。
formatter
'void'
numpystr
np.loadtxt
np.loadtxt 现在以块的形式读取文件,而不是同时读取所有文件,这将显著降低大型文件的内存使用率。
具有多个字段的结构化数组的索引和分配在很多方面都发生了变化,正如在以前的版本中所警告的那样。
首先,用多个字段对结构化数组进行索引,例如, arr[['f1', 'f3']] ,将视图返回到原始数组而不是副本中。返回的视图将具有与原始数组中的中间字段相对应的额外填充字节,这与1.13中的副本不同,后者将影响代码,如 arr[['f1', 'f3']].view(newdtype) .
arr[['f1', 'f3']]
arr[['f1', 'f3']].view(newdtype)
其次,结构化数组之间的赋值现在将“按位置”而不是“按字段名”。目标的第n个字段将设置为源的第n个字段,而不管字段名如何,与numpy版本1.6到1.13不同,在numpy版本中,目标数组中的字段被设置为源数组中同名的字段,或者如果源没有字段,则设置为0。
相应地,在计算数据类型相等性时,结构化数据类型中字段的顺序现在很重要。例如,使用dtypes::
x = dtype({'names': ['A', 'B'], 'formats': ['i4', 'f4'], 'offsets': [0, 4]}) y = dtype({'names': ['B', 'A'], 'formats': ['f4', 'i4'], 'offsets': [4, 0]})
表达式 x == y 现在将返回 False 与以前不同。这使得基于字典的数据类型规范 dtype({{'a': ('i4', 0), 'b': ('f4', 4)}}) 在python<3.6中很危险,因为这些版本中不保留dict键顺序。
x == y
False
dtype({{'a': ('i4', 0), 'b': ('f4', 4)}})
从结构化数组到布尔数组的赋值现在会引发ValueError,与1.13中的情况不同,它总是将目标元素设置为 True .
从具有多个字段的结构化数组到非结构化数组的赋值现在会引发ValueError。在1.13中,这只将源的第一个字段复制到目标。
现在不允许在多字段索引中使用字段“标题”,就像在多字段索引中重复字段名一样。
《用户指南》中结构化阵列的文档已显著更新,以反映这些更改。
np.set_string_function
以前,与大多数其他 NumPy scalar不同的是, str 和 repr 整数和无效标量的 np.set_string_function . 这已经不可能了。
以前 str 和 repr 在0d个数组中,有个特殊实现返回 str(a.item()) 和 'array(' + repr(a.item()) + ')' 分别用于0d数组 a 与numpy scalars和更高维度ndarrays不同。
str(a.item())
'array(' + repr(a.item()) + ')'
现在, str 0d数组的作用类似于使用 str(a[()]) 以及 repr 类似于使用 formatter(a[()]) 在哪里 formatter 可以使用指定 np.set_printoptions . 这个 style 的参数 np.array2string 被贬低。
str(a[()])
formatter(a[()])
此新行为在1.13传统打印模式下被禁用,请参阅上面的兼容性说明。
RandomState
RandomState 以前会接受空数组或具有2个或更多维度的数组,这会导致种子设定失败(空数组),或者在设置种子时忽略某些传递的值。
这个 repr A的 MaskedArray 现在更接近生成它的python代码,数组现在用逗号和dtypes显示。与其他格式更改一样,可以使用1.13传统打印模式禁用此设置,以帮助转换doctest。
np.polynomial
现在,它将域和窗口参数显示为关键字参数,以使它们更清晰:
>>> np.polynomial.Polynomial(range(4)) Polynomial([0., 1., 2., 3.], domain=[-1, 1], window=[-1, 1])