The Guide to NumPy gives detailed explanations (in particular see chapter 2.6.1, which is in the freely available sample chapters).
The strategy is to use a compatibility layer to convert Numeric code. The script found in site-packages/numpy/oldnumeric/alter_code1.py converts code written for Numeric to run with numpy using the compatibility layer.
You can convert an entire tree of .py, .h, and .c files from Numeric to use numpy by running
import numpy.oldnumeric.alter_code1 as noa
noa.converttree(<top_level>)
Be sure to have a back-up as this will overwrite all files in the directory with any changes. The detailed changes are found in alter_code1.py
Typechar changes
Numeric |
NumPy |
'b' |
'B' |
'1' |
'b' |
's' |
'h' |
'w' |
'H' |
'u' |
'I' |
Differing behaviour between Numeric and numpy
Length of scalar array
In Numeric the lenght of a scalar is 1:
>>> len(array(1)) 1
In numpy a TypeError is raised:
>>> len(array(1)) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: len() of unsized object
Array comparison
* Cannot use if arr1 == arr2: ....
Use if alltrue(arr1==arr2):... when shape(arr1)==shape(arr2) holds.
* assert(arr1==arr2) won't work. Use assert_equal(arr1, arr2) instead.
Misc
* with numpy arr.resize(...) returns None.
* Instead of ones(..., typecode=Float), use ones(..., Float) or ones(..., dtype=Float).
* Mixed operations with arrays scalars no longer up-cast the result if the scalar has higher precision. Arrays always control the output precision in array/scalar operations.
Differing behaviour between old scipy and numpy
* The square root of negative numbers is not defined. In old scipy the complex result was returned. You can get the extended behavior by explicitly importing the functions from numpy.lib.scimath
* The arccosine no longer gives an exception when called with an invalid argument (i.e. arccos(1.3)) but returns nan.
Extension module Changes
For simple extension modules just replacing Numeric/arrayobject.h with numpy/arrayobject.h should work. The CAPI of NumPy is backward compatible with the exposed API of Numeric.
There are a few non-standard Numeric usages (that were not really part of the API) that will need to be changed:
If you used any of the function pointers in the PyArray_Descr structure you will have to modify your usage of those. First, the pointers are all under the member named f. So descr->cast is now descr->f->cast. In addition, the casting functions have eliminated the strides argument (use PyArray_CastTo if you need strided casting). All functions have one or two PyArrayObject * arguments at the end. This allows the flexible arrays and mis-behaved arrays to be handled.
The descr->zero and descr->one constants have been replaced with function calls, PyArray_Zero, and PyArray_One (be sure to read the code and free the resulting memory if you use these calls).
If you passed array->dimensions and array->strides around to functions, you will need to fix some code. These are now npy_intp* pointers. On 32-bit systems there won't be a problem. However, on 64-bit systems, you will need to make changes to avoid errors and segfaults.
The header files arrayobject.h and ufuncobject.h contain many defines that you may find useful. The files ufunc_api.h and multiarray_api.h contain the available C-API function calls with their function signatures.
All of these headers are installed to the directory returned by numpy.get_include(). This directory is included in the list of include directories automatically if you are using numpy.distutils to create your extension module.