NumPy 1.21.0 Release Notes#
The NumPy 1.21.0 release highlights are
continued SIMD work covering more functions and platforms,
initial work on the new dtype infrastructure and casting,
universal2 wheels for Python 3.8 and Python 3.9 on Mac,
improved documentation,
improved annotations,
new
PCG64DXSMbitgenerator for random numbers.
In addition there are the usual large number of bug fixes and other improvements.
The Python versions supported for this release are 3.7-3.9. Official supportfor Python 3.10 will be added when it is released.
Warning
There are unresolved problems compiling NumPy 1.20.0 with gcc-11.1.
Optimization level-O3 results in many incorrect warnings whenrunning the tests.
On some hardware NumPY will hang in an infinite loop.
New functions#
AddPCG64DXSMBitGenerator#
Uses of thePCG64BitGenerator in a massively-parallel context have beenshown to have statistical weaknesses that were not apparent at the firstrelease in numpy 1.17. Most users will never observe this weakness and aresafe to continue to usePCG64. We have introduced a newPCG64DXSMBitGenerator that will eventually become the new defaultBitGeneratorimplementation used bydefault_rng in future releases.PCG64DXSM solvesthe statistical weakness while preserving the performance and the features ofPCG64.
SeeUpgrading PCG64 with PCG64DXSM for more details.
(gh-18906)
Expired deprecations#
The
shapeargumentunravel_indexcannot be passedasdimskeyword argument anymore. (Was deprecated in NumPy 1.16.)(gh-17900)
The function
PyUFunc_GenericFunctionhas been disabled.It was deprecated in NumPy 1.19. Users should call the ufuncdirectly using the Python API.(gh-18697)
The function
PyUFunc_SetUsesArraysAsDatahas been disabled.It was deprecated in NumPy 1.19.(gh-18697)
The class
PolyBasehas been removed (deprecated in numpy 1.9.0). Pleaseuse the abstractABCPolyBaseclass instead.(gh-18963)
The unused
PolyErrorandPolyDomainErrorexceptions areremoved.(gh-18963)
Deprecations#
The.dtype attribute must return adtype#
ADeprecationWarning is now given if the.dtype attributeof an object passed intonp.dtype or as adtype=obj argumentis not a dtype. NumPy will stop attempting to recursively coerce theresult of.dtype.
(gh-13578)
Inexact matches fornumpy.convolve andnumpy.correlate are deprecated#
convolve andcorrelate now emit a warning when there are caseinsensitive and/or inexact matches found formode argument in the functions.Pass full"same","valid","full" strings instead of"s","v","f" for themode argument.
(gh-17492)
np.typeDict has been formally deprecated#
np.typeDict is a deprecated alias fornp.sctypeDict andhas been so for over 14 years (6689502).A deprecation warning will now be issued whenever gettingnp.typeDict.
(gh-17586)
Exceptions will be raised during array-like creation#
When an object raised an exception during access of the specialattributes__array__ or__array_interface__, this exceptionwas usually ignored.A warning is now given when the exception is anything but AttributeError.To silence the warning, the type raising the exception has to be adaptedto raise anAttributeError.
(gh-19001)
Fourndarray.ctypes methods have been deprecated#
Four methods of thendarray.ctypes object have been deprecated,as they are (undocumentated) implementation artifacts of their respectiveproperties.
The methods in question are:
_ctypes.get_data(use_ctypes.datainstead)_ctypes.get_shape(use_ctypes.shapeinstead)_ctypes.get_strides(use_ctypes.stridesinstead)_ctypes.get_as_parameter(use_ctypes._as_parameter_instead)
(gh-19031)
Expired deprecations#
The
shapeargumentnumpy.unravel_indexcannot be passedasdimskeyword argument anymore. (Was deprecated in NumPy 1.16.)(gh-17900)
The function
PyUFunc_GenericFunctionhas been disabled.It was deprecated in NumPy 1.19. Users should call the ufuncdirectly using the Python API.(gh-18697)
The function
PyUFunc_SetUsesArraysAsDatahas been disabled.It was deprecated in NumPy 1.19.(gh-18697)
Remove deprecatedPolyBase and unusedPolyError andPolyDomainError#
The classPolyBase has been removed (deprecated in numpy 1.9.0). Please usethe abstractABCPolyBase class instead.
Furthermore, the unusedPolyError andPolyDomainError exceptions areremoved from thenumpy.polynomial.
(gh-18963)
Compatibility notes#
Error type changes in universal functions#
The universal functions may now raise different errors on invalid input in somecases. The main changes should be that aRuntimeError was replaced with amore fittingTypeError. When multiple errors were present in the samecall, NumPy may now raise a different one.
(gh-15271)
__array_ufunc__ argument validation#
NumPy will now partially validate arguments before calling__array_ufunc__.Previously, it was possible to pass on invalid arguments (such as anon-existing keyword argument) when dispatch was known to occur.
(gh-15271)
__array_ufunc__ and additional positional arguments#
Previously, all positionally passed arguments were checked for__array_ufunc__ support. In the case ofreduce,accumulate, andreduceat all arguments may be passed by position. This means that whenthey were passed by position, they could previously have been asked to handlethe ufunc call via__array_ufunc__. Since this depended on the way thearguments were passed (by position or by keyword), NumPy will now only dispatchon the input and output array. For example, NumPy will never dispatch on thewhere array in a reduction such asnp.add.reduce.
(gh-15271)
Validate input values inGenerator.uniform#
Checked thathigh-low>=0 innp.random.Generator.uniform. RaisesValueError iflow>high. Previously out-of-order inputs were acceptedand silently swapped, so that iflow>high, the value generated washigh+(low-high)*random().
(gh-17921)
/usr/include removed from default include paths#
The default include paths when building a package withnumpy.distutils nolonger include/usr/include. This path is normally added by the compiler,and hardcoding it can be problematic. In case this causes a problem, pleaseopen an issue. A workaround is documented in PR 18658.
(gh-18658)
Changes to comparisons withdtype=...#
When thedtype= (orsignature) arguments to comparisonufuncs (equal,less, etc.) is used, this will denotethe desired output dtype in the future.This means that:
np.equal(2, 3, dtype=object)
will give aFutureWarning that it will return anobjectarray in the future, which currently happens for:
np.equal(None, None, dtype=object)
due to the fact thatnp.array(None) is already an objectarray. (This also happens for some other dtypes.)
Since comparisons normally only return boolean arrays, providingany other dtype will always raise an error in the future andgive aDeprecationWarning now.
(gh-18718)
Changes todtype andsignature arguments in ufuncs#
The universal function argumentsdtype andsignaturewhich are also valid for reduction such asnp.add.reduce(which is the implementation fornp.sum) will now issuea warning when thedtype provided is not a “basic” dtype.
NumPy almost always ignored metadata, byteorder or time unitson these inputs. NumPy will now always ignore it and raise anerror if byteorder or time unit changed.The following are the most important examples of changes whichwill give the error. In some cases previously the informationstored was not ignored, in all of these an error is now raised:
# Previously ignored the byte-order (affect if non-native)np.add(3,5,dtype=">i32")# The biggest impact is for timedelta or datetimes:arr=np.arange(10,dtype="m8[s]")# The examples always ignored the time unit "ns":np.add(arr,arr,dtype="m8[ns]")np.maximum.reduce(arr,dtype="m8[ns]")# The following previously did use "ns" (as opposed to `arr.dtype`)np.add(3,5,dtype="m8[ns]")# Now return generic time unitsnp.maximum(arr,arr,dtype="m8[ns]")# Now returns "s" (from `arr`)
The same applies for functions likenp.sum which use these internally.This change is necessary to achieve consistent handling within NumPy.
If you run into these, in most cases pass for exampledtype=np.timedelta64which clearly denotes a generaltimedelta64 without any unit or byte-orderdefined. If you need to specify the output dtype precisely, you may do soby either casting the inputs or providing an output array usingout=.
NumPy may choose to allow providing an exact outputdtype here in thefuture, which would be preceded by aFutureWarning.
(gh-18718)
Ufuncsignature=... anddtype= generalization andcasting#
The behaviour fornp.ufunc(1.0,1.0,signature=...) ornp.ufunc(1.0,1.0,dtype=...) can now yield different loops in 1.21compared to 1.20 because of changes in promotion.Whensignature was previously used, the casting check on inputswas relaxed, which could lead to downcasting inputs unsafely especiallyif combined withcasting="unsafe".
Casting is now guaranteed to be safe. If a signature is onlypartially provided, for example usingsignature=("float64",None,None),this could lead to no loop being found (an error).In that case, it is necessary to provide the complete signatureto enforce casting the inputs.Ifdtype="float64" is used or only outputs are set (e.g.signature=(None,None,"float64") the is unchanged.We expect that very few users are affected by this change.
Further, the meaning ofdtype="float64" has been slightly modified andnow strictly enforces only the correct output (and not input) DTypes.This means it is now always equivalent to:
signature=(None,None,"float64")
(If the ufunc has two inputs and one output). Since this could leadto no loop being found in some cases, NumPy will normally also searchfor the loop:
signature=("float64","float64","float64")
if the first search failed.In the future, this behaviour may be customized to achieve the expectedresults for more complex ufuncs. (For some universal functions such asnp.ldexp inputs can have different DTypes.)
(gh-18880)
Distutils forces strict floating point model on clang#
NumPy distutils will now always add the-ffp-exception-behavior=strictcompiler flag when compiling with clang. Clang defaults to a non-strictversion, which allows the compiler to generate code that does not setfloating point warnings/errors correctly.
(gh-19049)
C API changes#
Use ofufunc->type_resolver and “type tuple”#
NumPy now normalizes the “type tuple” argument to the type resolver functionsbefore calling it. Note that in the use of this type resolver is legacybehaviour and NumPy will not do so when possible. Callingufunc->type_resolver orPyUFunc_DefaultTypeResolver is stronglydiscouraged and will now enforce a normalized type tuple if done. Note thatthis does not affect providing a type resolver, which is expected to keepworking in most circumstances. If you have an unexpected use-case for callingthe type resolver, please inform the NumPy developers so that a solution can befound.
(gh-18718)
New Features#
Added a mypy plugin for handling platform-specificnumpy.number precisions#
Amypy plugin is now available for automatically assigning the (platform-dependent)precisions of certainnumber subclasses, including the likes ofint_,intp andlonglong. See the documentation onscalar types for a comprehensive overviewof the affected classes.
Note that while usage of the plugin is completely optional, without it theprecision of above-mentioned classes will be inferred asAny.
To enable the plugin, one must add it to their mypyconfiguration file:
[mypy]plugins=numpy.typing.mypy_plugin
(gh-17843)
Let the mypy plugin manage extended-precisionnumpy.number subclasses#
Themypy plugin, introduced innumpy/numpy#17843, has been expanded:the plugin now removes annotations for platform-specific extended-precisiontypes that are not available to the platform in question.For example, it will removefloat128 when not available.
Without the pluginall extended-precision types will, as far as mypy is concerned,be available on all platforms.
To enable the plugin, one must add it to their mypyconfiguration file:
[mypy]plugins=numpy.typing.mypy_plugin
(gh-18322)
Newmin_digits argument for printing float values#
A newmin_digits argument has been added to the dragon4 float printingfunctionsformat_float_positional andformat_float_scientific. This kwd guarantees that at least the given number of digits will be printedwhen printing in unique=True mode, even if the extra digits are unnecessary touniquely specify the value. It is the counterpart to the precision argumentwhich sets the maximum number of digits to be printed. When unique=False infixed precision mode, it has no effect and the precision argument fixes thenumber of digits.
(gh-18629)
f2py now recognizes Fortran abstract interface blocks#
f2py can now parse abstract interface blocks.
(gh-18695)
BLAS and LAPACK configuration via environment variables#
Autodetection of installed BLAS and LAPACK libraries can be bypassed by usingtheNPY_BLAS_LIBS andNPY_LAPACK_LIBS environment variables. Instead,the link flags in these environment variables will be used directly, and thelanguage is assumed to be F77. This is especially useful in automated buildswhere the BLAS and LAPACK that are installed are known exactly. A use case isreplacing the actual implementation at runtime via stub library links.
IfNPY_CBLAS_LIBS is set (optional in addition toNPY_BLAS_LIBS), thiswill be used as well, by definingHAVE_CBLAS and appending the environmentvariable content to the link flags.
(gh-18737)
A runtime-subcriptable alias has been added forndarray#
numpy.typing.NDArray has been added, a runtime-subscriptable alias fornp.ndarray[Any,np.dtype[~Scalar]]. The new type alias can be usedfor annotating arrays with a given dtype and unspecified shape.1
1 NumPy does not support the annotating of array shapes as of 1.21,this is expected to change in the future though (seePEP 646).
Examples#
>>>importnumpyasnp>>>importnumpy.typingasnpt>>>print(npt.NDArray)numpy.ndarray[typing.Any, numpy.dtype[~ScalarType]]>>>print(npt.NDArray[np.float64])numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]>>>NDArrayInt=npt.NDArray[np.int_]>>>a:NDArrayInt=np.arange(10)>>>deffunc(a:npt.ArrayLike)->npt.NDArray[Any]:...returnnp.array(a)
(gh-18935)
Improvements#
Arbitraryperiod option fornumpy.unwrap#
The size of the interval over which phases are unwrapped is no longer restricted to2*pi.This is especially useful for unwrapping degrees, but can also be used for other intervals.
>>>phase_deg=np.mod(np.linspace(0,720,19),360)-180>>>phase_degarray([-180., -140., -100., -60., -20., 20., 60., 100., 140., -180., -140., -100., -60., -20., 20., 60., 100., 140., -180.])>>>unwrap(phase_deg,period=360)array([-180., -140., -100., -60., -20., 20., 60., 100., 140., 180., 220., 260., 300., 340., 380., 420., 460., 500., 540.])
(gh-16987)
np.unique now returns singleNaN#
Whennp.unique operated on an array with multipleNaN entries,its return included aNaN for each entry that wasNaN in the original array.This is now improved such that the returned array contains just oneNaN as thelast element.
Also for complex arrays allNaN values are considered equivalent(no matter whether theNaN is in the real or imaginary part). As therepresentant for the returned array the smallest one in thelexicographical order is chosen - seenp.sort for how the lexicographicalorder is defined for complex arrays.
(gh-18070)
Generator.rayleigh andGenerator.geometric performance improved#
The performance of Rayleigh and geometric random variate generationinGenerator has improved. These are both transformation of exponentialrandom variables and the slow log-based inverse cdf transformation hasbeen replaced with the Ziggurat-based exponential variate generator.
This change breaks the stream of variates generated when variates fromeither of these distributions are produced.
(gh-18666)
Placeholder annotations have been improved#
All placeholder annotations, that were previously annotated astyping.Any,have been improved. Where appropriate they have been replaced with explicitfunction definitions, classes or other miscellaneous objects.
(gh-18934)
Performance improvements#
Improved performance in integer division of NumPy arrays#
Integer division of NumPy arrays now useslibdivide when the divisor is a constant. With theusage of libdivide and other minor optimizations, there is a large speedup.The// operator andnp.floor_divide makes use of the new changes.
(gh-17727)
Improve performance ofnp.save andnp.load for small arrays#
np.save is now a lot faster for small arrays.
np.load is also faster for small arrays,but only when serializing with a version >=(3,0).
Both are done by removing checks that are only relevant for Python 2,while still maintaining compatibility with arrayswhich might have been created by Python 2.
(gh-18657)
Changes#
numpy.piecewise output class now matches the input class#
Whenndarray subclasses are used on input topiecewise,they are passed on to the functions. The output will now be of thesame subclass as well.
(gh-18110)
Enable Accelerate Framework#
With the release of macOS 11.3, several different issues that numpy wasencountering when using Accelerate Framework’s implementation of BLAS andLAPACK should be resolved. This change enables the Accelerate Framework as anoption on macOS. If additional issues are found, please file a bug reportagainst Accelerate using the developer feedback assistant tool(https://developer.apple.com/bug-reporting/). We intend to address issuespromptly and plan to continue supporting and updating our BLAS and LAPACKlibraries.
(gh-18874)