diff options
author | Charles Harris <charlesr.harris@gmail.com> | 2015-10-25 09:03:01 -0600 |
---|---|---|
committer | Charles Harris <charlesr.harris@gmail.com> | 2015-10-25 09:03:01 -0600 |
commit | 53d7e68b410ca00a825899a8a766bba3ba77cbc3 (patch) | |
tree | b1eebcb4b2ab3a2b1881c498fa2f621aa73a4783 /doc | |
parent | 42fefc59a502d1b17873d19f9d60d039e55ccfc4 (diff) | |
parent | 4b1f1243fb2b2eb35adf50a26b0c4d2bcc3a7709 (diff) | |
download | numpy-53d7e68b410ca00a825899a8a766bba3ba77cbc3.tar.gz |
Merge pull request #6560 from pv/userguide-up
DOC: user guide update
Diffstat (limited to 'doc')
-rw-r--r-- | doc/source/reference/routines.rst | 2 | ||||
-rw-r--r-- | doc/source/user/basics.rst | 2 | ||||
-rw-r--r-- | doc/source/user/building.rst | 143 | ||||
-rw-r--r-- | doc/source/user/howtofind.rst | 7 | ||||
-rw-r--r-- | doc/source/user/index.rst | 22 | ||||
-rw-r--r-- | doc/source/user/install.rst | 197 | ||||
-rw-r--r-- | doc/source/user/introduction.rst | 10 | ||||
-rw-r--r-- | doc/source/user/misc.rst | 2 | ||||
-rw-r--r-- | doc/source/user/numpy-for-matlab-users.rst | 695 | ||||
-rw-r--r-- | doc/source/user/performance.rst | 5 | ||||
-rw-r--r-- | doc/source/user/quickstart.rst | 1414 | ||||
-rw-r--r-- | doc/source/user/setting-up.rst | 9 |
12 files changed, 2276 insertions, 232 deletions
diff --git a/doc/source/reference/routines.rst b/doc/source/reference/routines.rst index c2f091d83..a9e80480b 100644 --- a/doc/source/reference/routines.rst +++ b/doc/source/reference/routines.rst @@ -1,3 +1,5 @@ +.. _routines: + ******** Routines ******** diff --git a/doc/source/user/basics.rst b/doc/source/user/basics.rst index bbc3ab174..1d91cc55c 100644 --- a/doc/source/user/basics.rst +++ b/doc/source/user/basics.rst @@ -3,7 +3,7 @@ Numpy basics ************ .. toctree:: - :maxdepth: 2 + :maxdepth: 1 basics.types basics.creation diff --git a/doc/source/user/building.rst b/doc/source/user/building.rst new file mode 100644 index 000000000..c5f8fea1f --- /dev/null +++ b/doc/source/user/building.rst @@ -0,0 +1,143 @@ +.. _building-from-source: + +Building from source +==================== + +A general overview of building NumPy from source is given here, with detailed +instructions for specific platforms given seperately. + +Prerequisites +------------- + +Building NumPy requires the following software installed: + +1) Python 2.6.x, 2.7.x, 3.2.x or newer + + On Debian and derivatives (Ubuntu): python, python-dev (or python3-dev) + + On Windows: the official python installer at + `www.python.org <http://www.python.org>`_ is enough + + Make sure that the Python package distutils is installed before + continuing. For example, in Debian GNU/Linux, installing python-dev + also installs distutils. + + Python must also be compiled with the zlib module enabled. This is + practically always the case with pre-packaged Pythons. + +2) Compilers + + To build any extension modules for Python, you'll need a C compiler. + Various NumPy modules use FORTRAN 77 libraries, so you'll also need a + FORTRAN 77 compiler installed. + + Note that NumPy is developed mainly using GNU compilers. Compilers from + other vendors such as Intel, Absoft, Sun, NAG, Compaq, Vast, Porland, + Lahey, HP, IBM, Microsoft are only supported in the form of community + feedback, and may not work out of the box. GCC 4.x (and later) compilers + are recommended. + +3) Linear Algebra libraries + + NumPy does not require any external linear algebra libraries to be + installed. However, if these are available, NumPy's setup script can detect + them and use them for building. A number of different LAPACK library setups + can be used, including optimized LAPACK libraries such as ATLAS, MKL or the + Accelerate/vecLib framework on OS X. + +Basic Installation +------------------ + +To install NumPy run:: + + python setup.py install + +To perform an in-place build that can be run from the source folder run:: + + python setup.py build_ext --inplace + +The NumPy build system uses ``distutils`` and ``numpy.distutils``. +``setuptools`` is only used when building via ``pip`` or with ``python +setupegg.py``. Using ``virtualenv`` should work as expected. + +*Note: for build instructions to do development work on NumPy itself, see +:ref:`development-environment`*. + +.. _parallel-builds: + +Parallel builds +~~~~~~~~~~~~~~~ + +From NumPy 1.10.0 on it's also possible to do a parallel build with:: + + python setup.py build -j 4 install --prefix $HOME/.local + +This will compile numpy on 4 CPUs and install it into the specified prefix. +to perform a parallel in-place build, run:: + + python setup.py build_ext --inplace -j 4 + +The number of build jobs can also be specified via the environment variable +``NPY_NUM_BUILD_JOBS``. + + +FORTRAN ABI mismatch +-------------------- + +The two most popular open source fortran compilers are g77 and gfortran. +Unfortunately, they are not ABI compatible, which means that concretely you +should avoid mixing libraries built with one with another. In particular, if +your blas/lapack/atlas is built with g77, you *must* use g77 when building +numpy and scipy; on the contrary, if your atlas is built with gfortran, you +*must* build numpy/scipy with gfortran. This applies for most other cases +where different FORTRAN compilers might have been used. + +Choosing the fortran compiler +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To build with g77:: + + python setup.py build --fcompiler=gnu + +To build with gfortran:: + + python setup.py build --fcompiler=gnu95 + +For more information see:: + + python setup.py build --help-fcompiler + +How to check the ABI of blas/lapack/atlas +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +One relatively simple and reliable way to check for the compiler used to build +a library is to use ldd on the library. If libg2c.so is a dependency, this +means that g77 has been used. If libgfortran.so is a a dependency, gfortran +has been used. If both are dependencies, this means both have been used, which +is almost always a very bad idea. + +Disabling ATLAS and other accelerated libraries +----------------------------------------------- + +Usage of ATLAS and other accelerated libraries in Numpy can be disabled +via:: + + BLAS=None LAPACK=None ATLAS=None python setup.py build + + +Supplying additional compiler flags +----------------------------------- + +Additional compiler flags can be supplied by setting the ``OPT``, +``FOPT`` (for Fortran), and ``CC`` environment variables. + + +Building with ATLAS support +--------------------------- + +Ubuntu +~~~~~~ + +You can install the necessary package for optimized ATLAS with this command:: + + sudo apt-get install libatlas-base-dev diff --git a/doc/source/user/howtofind.rst b/doc/source/user/howtofind.rst deleted file mode 100644 index 00ed5daa7..000000000 --- a/doc/source/user/howtofind.rst +++ /dev/null @@ -1,7 +0,0 @@ -************************* -How to find documentation -************************* - -.. seealso:: :ref:`Numpy-specific help functions <routines.help>` - -.. automodule:: numpy.doc.howtofind diff --git a/doc/source/user/index.rst b/doc/source/user/index.rst index 022efcaeb..a45fec9ec 100644 --- a/doc/source/user/index.rst +++ b/doc/source/user/index.rst @@ -9,25 +9,13 @@ explains how to install and make use of the most important features of NumPy. For detailed reference documentation of the functions and classes contained in the package, see the :ref:`reference`. -.. warning:: - - This "User Guide" is still a work in progress; some of the material - is not organized, and several aspects of NumPy are not yet covered - sufficient detail. We are an open source community continually - working to improve the documentation and eagerly encourage interested - parties to contribute. For information on how to do so, please visit - the NumPy `doc wiki <http://docs.scipy.org/numpy/Front%20Page>`_. - - More documentation for NumPy can be found on the `numpy.org - <http://www.numpy.org>`__ website. - - Thanks! - .. toctree:: - :maxdepth: 2 + :maxdepth: 1 - introduction + setting-up + quickstart basics - performance misc + numpy-for-matlab-users + building c-info diff --git a/doc/source/user/install.rst b/doc/source/user/install.rst index dcf20498c..ebb6bce62 100644 --- a/doc/source/user/install.rst +++ b/doc/source/user/install.rst @@ -1,194 +1,11 @@ -***************************** -Building and installing NumPy -***************************** - -Binary installers -================= +**************** +Installing NumPy +**************** In most use cases the best way to install NumPy on your system is by using an -installable binary package for your operating system. - -Windows -------- - -Good solutions for Windows are, `Enthought Canopy -<https://www.enthought.com/products/canopy/>`_, `Anaconda -<http://continuum.io/downloads.html>`_ (which both provide binary installers -for Windows, OS X and Linux) and `Python (x, y) <http://www.pythonxy.com>`_. -Both of these packages include Python, NumPy and many additional packages. - -A lightweight alternative is to download the Python -installer from `www.python.org <http://www.python.org>`_ and the NumPy -installer for your Python version from the Sourceforge `download site -<http://sourceforge.net/projects/numpy/files/NumPy`_. - -The NumPy installer includes binaries for different CPU's (without SSE -instructions, with SSE2 or with SSE3) and installs the correct one -automatically. If needed, this can be bypassed from the command line with :: - - numpy-<1.y.z>-superpack-win32.exe /arch nosse - -or ``sse2`` or ``sse3`` instead of ``nosse``. - -Linux ------ - -All major distributions provide packages for NumPy. These are usually -reasonably up-to-date, but sometimes lag behind the most recent NumPy release. - -Mac OS X --------- - -Universal binary installers for NumPy are available from the `download site -<http://sourceforge.net/projects/numpy/files/NumPy`_, and wheel packages -from PyPi. With a recent version of `pip`<https://pip.pypa.io/en/latest/>`_ -this will give you a binary install (from the wheel packages) compatible with -at python.org Python, Homebrew and MacPorts:: - - pip install numpy - - -.. _building-from-source: - -Building from source -==================== - -A general overview of building NumPy from source is given here, with detailed -instructions for specific platforms given seperately. - -Prerequisites -------------- - -Building NumPy requires the following software installed: - -1) Python 2.6.x, 2.7.x, 3.2.x or newer - - On Debian and derivatives (Ubuntu): python, python-dev (or python3-dev) - - On Windows: the official python installer at - `www.python.org <http://www.python.org>`_ is enough - - Make sure that the Python package distutils is installed before - continuing. For example, in Debian GNU/Linux, installing python-dev - also installs distutils. - - Python must also be compiled with the zlib module enabled. This is - practically always the case with pre-packaged Pythons. - -2) Compilers - - To build any extension modules for Python, you'll need a C compiler. - Various NumPy modules use FORTRAN 77 libraries, so you'll also need a - FORTRAN 77 compiler installed. - - Note that NumPy is developed mainly using GNU compilers. Compilers from - other vendors such as Intel, Absoft, Sun, NAG, Compaq, Vast, Porland, - Lahey, HP, IBM, Microsoft are only supported in the form of community - feedback, and may not work out of the box. GCC 4.x (and later) compilers - are recommended. - -3) Linear Algebra libraries - - NumPy does not require any external linear algebra libraries to be - installed. However, if these are available, NumPy's setup script can detect - them and use them for building. A number of different LAPACK library setups - can be used, including optimized LAPACK libraries such as ATLAS, MKL or the - Accelerate/vecLib framework on OS X. - -Basic Installation ------------------- - -To install NumPy run:: - - python setup.py install - -To perform an in-place build that can be run from the source folder run:: - - python setup.py build_ext --inplace - -The NumPy build system uses ``distutils`` and ``numpy.distutils``. -``setuptools`` is only used when building via ``pip`` or with ``python -setupegg.py``. Using ``virtualenv`` should work as expected. - -*Note: for build instructions to do development work on NumPy itself, see -:ref:`development-environment`*. - -.. _parallel-builds: - -Parallel builds -~~~~~~~~~~~~~~~ - -From NumPy 1.10.0 on it's also possible to do a parallel build with:: - - python setup.py build -j 4 install --prefix $HOME/.local - -This will compile numpy on 4 CPUs and install it into the specified prefix. -to perform a parallel in-place build, run:: - - python setup.py build_ext --inplace -j 4 - -The number of build jobs can also be specified via the environment variable -``NPY_NUM_BUILD_JOBS``. - - -FORTRAN ABI mismatch --------------------- - -The two most popular open source fortran compilers are g77 and gfortran. -Unfortunately, they are not ABI compatible, which means that concretely you -should avoid mixing libraries built with one with another. In particular, if -your blas/lapack/atlas is built with g77, you *must* use g77 when building -numpy and scipy; on the contrary, if your atlas is built with gfortran, you -*must* build numpy/scipy with gfortran. This applies for most other cases -where different FORTRAN compilers might have been used. - -Choosing the fortran compiler -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To build with g77:: - - python setup.py build --fcompiler=gnu - -To build with gfortran:: - - python setup.py build --fcompiler=gnu95 - -For more information see:: - - python setup.py build --help-fcompiler - -How to check the ABI of blas/lapack/atlas -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -One relatively simple and reliable way to check for the compiler used to build -a library is to use ldd on the library. If libg2c.so is a dependency, this -means that g77 has been used. If libgfortran.so is a a dependency, gfortran -has been used. If both are dependencies, this means both have been used, which -is almost always a very bad idea. - -Disabling ATLAS and other accelerated libraries ------------------------------------------------ - -Usage of ATLAS and other accelerated libraries in Numpy can be disabled -via:: - - BLAS=None LAPACK=None ATLAS=None python setup.py build - - -Supplying additional compiler flags ------------------------------------ - -Additional compiler flags can be supplied by setting the ``OPT``, -``FOPT`` (for Fortran), and ``CC`` environment variables. - - -Building with ATLAS support ---------------------------- - -Ubuntu -~~~~~~ - -You can install the necessary package for optimized ATLAS with this command:: +pre-built package for your operating system. - sudo apt-get install libatlas-base-dev +Please see http://scipy.org/install.html for links to available options. +For instructions on building for source package, see +:doc:`building`. This information is useful mainly for advanced users. diff --git a/doc/source/user/introduction.rst b/doc/source/user/introduction.rst deleted file mode 100644 index d29c13b30..000000000 --- a/doc/source/user/introduction.rst +++ /dev/null @@ -1,10 +0,0 @@ -************ -Introduction -************ - - -.. toctree:: - - whatisnumpy - install - howtofind diff --git a/doc/source/user/misc.rst b/doc/source/user/misc.rst index 0e1807f3f..c10aea486 100644 --- a/doc/source/user/misc.rst +++ b/doc/source/user/misc.rst @@ -3,5 +3,3 @@ Miscellaneous ************* .. automodule:: numpy.doc.misc - -.. automodule:: numpy.doc.methods_vs_functions diff --git a/doc/source/user/numpy-for-matlab-users.rst b/doc/source/user/numpy-for-matlab-users.rst new file mode 100644 index 000000000..2b8f43749 --- /dev/null +++ b/doc/source/user/numpy-for-matlab-users.rst @@ -0,0 +1,695 @@ +.. _numpy-for-matlab-users: + +====================== +Numpy for Matlab users +====================== + +Introduction +============ + +MATLAB® and NumPy/SciPy have a lot in common. But +there are many differences. NumPy and SciPy were created to do numerical +and scientific computing in the most natural way with Python, not to be +MATLAB® clones. This page is intended to be a place to collect wisdom +about the differences, mostly for the purpose of helping proficient +MATLAB® users become proficient NumPy and SciPy users. + +.. raw:: html + + <style> + table.docutils td { border: solid 1px #ccc; } + </style> + +Some Key Differences +==================== + +.. list-table:: + + * - In MATLAB®, the basic data type is a multidimensional array of double precision floating point numbers. Most expressions take such arrays and return such arrays. Operations on the 2-D instances of these arrays are designed to act more or less like matrix operations in linear algebra. + - In NumPy the basic type is a multidimensional ``array``. Operations on these arrays in all dimensionalities including 2D are elementwise operations. However, there is a special ``matrix`` type for doing linear algebra, which is just a subclass of the ``array`` class. Operations on matrix-class arrays are linear algebra operations. + + * - MATLAB® uses 1 (one) based indexing. The initial element of a sequence is found using a(1). + :ref:`See note INDEXING <numpy-for-matlab-users.notes>` + - Python uses 0 (zero) based indexing. The initial element of a sequence is found using a[0]. + + * - MATLAB®'s scripting language was created for doing linear algebra. The syntax for basic matrix operations is nice and clean, but the API for adding GUIs and making full-fledged applications is more or less an afterthought. + - NumPy is based on Python, which was designed from the outset to be an excellent general-purpose programming language. While Matlab's syntax for some array manipulations is more compact than NumPy's, NumPy (by virtue of being an add-on to Python) can do many things that Matlab just cannot, for instance subclassing the main array type to do both array and matrix math cleanly. + + * - In MATLAB®, arrays have pass-by-value semantics, with a lazy copy-on-write scheme to prevent actually creating copies until they are actually needed. Slice operations copy parts of the array. + - In NumPy arrays have pass-by-reference semantics. Slice operations are views into an array. + + +'array' or 'matrix'? Which should I use? +======================================== + +Numpy provides, in addition to `np.ndarray`` an additional matrix type +that you may see used in some existing code. Which one to use? + +Short answer +------------ + +**Use arrays**. + +- They are the standard vector/matrix/tensor type of numpy. Many numpy + function return arrays, not matrices. +- There is a clear distinction between element-wise operations and + linear algebra operations. +- You can have standard vectors or row/column vectors if you like. + +The only disadvantage of using the array type is that you will have to +use ``dot`` instead of ``*`` to multiply (reduce) two tensors (scalar +product, matrix vector multiplication etc.). + +Long answer +----------- + +Numpy contains both an ``array`` class and a ``matrix`` class. The +``array`` class is intended to be a general-purpose n-dimensional array +for many kinds of numerical computing, while ``matrix`` is intended to +facilitate linear algebra computations specifically. In practice there +are only a handful of key differences between the two. + +- Operator ``*``, ``dot()``, and ``multiply()``: + + - For ``array``, **'``*``\ ' means element-wise multiplication**, + and the ``dot()`` function is used for matrix multiplication. + - For ``matrix``, **'``*``\ ' means matrix multiplication**, and the + ``multiply()`` function is used for element-wise multiplication. + +- Handling of vectors (rank-1 arrays) + + - For ``array``, the **vector shapes 1xN, Nx1, and N are all + different things**. Operations like ``A[:,1]`` return a rank-1 + array of shape N, not a rank-2 of shape Nx1. Transpose on a rank-1 + ``array`` does nothing. + - For ``matrix``, **rank-1 arrays are always upconverted to 1xN or + Nx1 matrices** (row or column vectors). ``A[:,1]`` returns a + rank-2 matrix of shape Nx1. + +- Handling of higher-rank arrays (rank > 2) + + - ``array`` objects **can have rank > 2**. + - ``matrix`` objects **always have exactly rank 2**. + +- Convenience attributes + + - ``array`` **has a .T attribute**, which returns the transpose of + the data. + - ``matrix`` **also has .H, .I, and .A attributes**, which return + the conjugate transpose, inverse, and ``asarray()`` of the matrix, + respectively. + +- Convenience constructor + + - The ``array`` constructor **takes (nested) Python sequences as + initializers**. As in, ``array([[1,2,3],[4,5,6]])``. + - The ``matrix`` constructor additionally **takes a convenient + string initializer**. As in ``matrix("[1 2 3; 4 5 6]")``. + +There are pros and cons to using both: + +- ``array`` + + - ``:)`` You can treat rank-1 arrays as *either* row or column + vectors. ``dot(A,v)`` treats ``v`` as a column vector, while + ``dot(v,A)`` treats ``v`` as a row vector. This can save you + having to type a lot of transposes. + - ``<:(`` Having to use the ``dot()`` function for matrix-multiply is + messy -- ``dot(dot(A,B),C)`` vs. ``A*B*C``. + - ``:)`` Element-wise multiplication is easy: ``A*B``. + - ``:)`` ``array`` is the "default" NumPy type, so it gets the most + testing, and is the type most likely to be returned by 3rd party + code that uses NumPy. + - ``:)`` Is quite at home handling data of any rank. + - ``:)`` Closer in semantics to tensor algebra, if you are familiar + with that. + - ``:)`` *All* operations (``*``, ``/``, ``+``, ```` etc.) are + elementwise + +- ``matrix`` + + - ``:\\`` Behavior is more like that of MATLAB® matrices. + - ``<:(`` Maximum of rank-2. To hold rank-3 data you need ``array`` or + perhaps a Python list of ``matrix``. + - ``<:(`` Minimum of rank-2. You cannot have vectors. They must be + cast as single-column or single-row matrices. + - ``<:(`` Since ``array`` is the default in NumPy, some functions may + return an ``array`` even if you give them a ``matrix`` as an + argument. This shouldn't happen with NumPy functions (if it does + it's a bug), but 3rd party code based on NumPy may not honor type + preservation like NumPy does. + - ``:)`` ``A*B`` is matrix multiplication, so more convenient for + linear algebra. + - ``<:(`` Element-wise multiplication requires calling a function, + ``multipy(A,B)``. + - ``<:(`` The use of operator overloading is a bit illogical: ``*`` + does not work elementwise but ``/`` does. + +The ``array`` is thus much more advisable to use. + +Facilities for Matrix Users +=========================== + +Numpy has some features that facilitate the use of the ``matrix`` type, +which hopefully make things easier for Matlab converts. + +- A ``matlib`` module has been added that contains matrix versions of + common array constructors like ``ones()``, ``zeros()``, ``empty()``, + ``eye()``, ``rand()``, ``repmat()``, etc. Normally these functions + return ``array``\ s, but the ``matlib`` versions return ``matrix`` + objects. +- ``mat`` has been changed to be a synonym for ``asmatrix``, rather + than ``matrix``, thus making it concise way to convert an ``array`` + to a ``matrix`` without copying the data. +- Some top-level functions have been removed. For example + ``numpy.rand()`` now needs to be accessed as ``numpy.random.rand()``. + Or use the ``rand()`` from the ``matlib`` module. But the + "numpythonic" way is to use ``numpy.random.random()``, which takes a + tuple for the shape, like other numpy functions. + +Table of Rough MATLAB-NumPy Equivalents +======================================= + +The table below gives rough equivalents for some common MATLAB® +expressions. **These are not exact equivalents**, but rather should be +taken as hints to get you going in the right direction. For more detail +read the built-in documentation on the NumPy functions. + +Some care is necessary when writing functions that take arrays or +matrices as arguments --- if you are expecting an ``array`` and are +given a ``matrix``, or vice versa, then '\*' (multiplication) will give +you unexpected results. You can convert back and forth between arrays +and matrices using + +- ``asarray``: always returns an object of type ``array`` +- ``asmatrix`` or ``mat``: always return an object of type + ``matrix`` +- ``asanyarray``: always returns an ``array`` object or a subclass + derived from it, depending on the input. For instance if you pass in + a ``matrix`` it returns a ``matrix``. + +These functions all accept both arrays and matrices (among other things +like Python lists), and thus are useful when writing functions that +should accept any array-like object. + +In the table below, it is assumed that you have executed the following +commands in Python: + +:: + + from numpy import * + import scipy.linalg + +Also assume below that if the Notes talk about "matrix" that the +arguments are rank 2 entities. + +General Purpose Equivalents +--------------------------- + +.. list-table:: + :header-rows: 1 + + * - **MATLAB** + - **numpy** + - **Notes** + * - ``help func`` + - ``info(func)`` or ``help(func)`` or ``func?`` (in Ipython) + - get help on the function *func* + * - ``which func`` + - `see note HELP <numpy-for-matlab-users.notes>`__ + - find out where *func* is defined + * - ``type func`` + - ``source(func)`` or ``func??`` (in Ipython) + - print source for *func* (if not a native function) + * - ``a && b`` + - ``a and b`` + - short-circuiting logical AND operator (Python native operator); scalar arguments only + * - ``a || b`` + - ``a or b`` + - short-circuiting logical OR operator (Python native operator); scalar arguments only + * - ``1*i``, ``1*j``, ``1i``, ``1j`` + - ``1j`` + - complex numbers + * - ``eps`` + - ``np.spacing(1)`` + - Distance between 1 and the nearest floating point number + * - ``ode45`` + - ``scipy.integrate.ode(f).set_integrator('dopri5')`` + - integrate an ODE with Runge-Kutta 4,5 + * - ``ode15s`` + - ``scipy.integrate.ode(f).set_integrator('vode', method='bdf', order=15)`` + - integrate an ODE with BDF method + +Linear Algebra Equivalents +-------------------------- + +.. list-table:: + :header-rows: 1 + + * - MATLAB + - NumPy + - Notes + + * - ``ndims(a)`` + - ``ndim(a)`` or ``a.ndim`` + - get the number of dimensions of a (tensor rank) + + * - ``numel(a)`` + - ``size(a)`` or ``a.size`` + - get the number of elements of an array + + * - ``size(a)`` + - ``shape(a)`` or ``a.shape`` + - get the "size" of the matrix + + * - ``size(a,n)`` + - ``a.shape[n-1]`` + - get the number of elements of the n-th dimension of array a. (Note that MATLAB® uses 1 based indexing while Python uses 0 based indexing, See note :ref:`INDEXING <numpy-for-matlab-users.notes>`) + + * - ``[ 1 2 3; 4 5 6 ]`` + - ``array([[1.,2.,3.], [4.,5.,6.]])`` + - 2x3 matrix literal + + * - ``[ a b; c d ]`` + - ``vstack([hstack([a,b]), hstack([c,d])])`` or + ``bmat('a b; c d').A`` + - construct a matrix from blocks a,b,c, and d + + * - ``a(end)`` + - ``a[-1]`` + - access last element in the 1xn matrix ``a`` + + * - ``a(2,5)`` + - ``a[1,4]`` + - access element in second row, fifth column + + * - ``a(2,:)`` + - ``a[1]`` or ``a[1,:]`` + - entire second row of ``a`` + + * - ``a(1:5,:)`` + - ``a[0:5]`` or ``a[:5]`` or ``a[0:5,:]`` + - the first five rows of ``a`` + + * - ``a(end-4:end,:)`` + - ``a[-5:]`` + - the last five rows of ``a`` + + * - ``a(1:3,5:9)`` + - ``a[0:3][:,4:9]`` + - rows one to three and columns five to nine of ``a``. This gives read-only access. + + * - ``a([2,4,5],[1,3])`` + - ``a[ix_([1,3,4],[0,2])]`` + - rows 2,4 and 5 and columns 1 and 3. This allows the matrix to be modified, and doesn't require a regular slice. + + * - ``a(3:2:21,:)`` + - ``a[ 2:21:2,:]`` + - every other row of ``a``, starting with the third and going to the twenty-first + + * - ``a(1:2:end,:)`` + - ``a[ ::2,:]`` + - every other row of ``a``, starting with the first + + * - ``a(end:-1:1,:)`` or ``flipud(a)`` + - ``a[ ::-1,:]`` + - ``a`` with rows in reverse order + + * - ``a([1:end 1],:)`` + - ``a[r_[:len(a),0]]`` + - ``a`` with copy of the first row appended to the end + + * - ``a.'`` + - ``a.transpose()`` or ``a.T`` + - transpose of ``a`` + + * - ``a'`` + - ``a.conj().transpose()`` or ``a.conj().T`` + - conjugate transpose of ``a`` + + * - ``a * b`` + - ``a.dot(b)`` + - matrix multiply + + * - ``a .* b`` + - ``a * b`` + - element-wise multiply + + * - ``a./b`` + - ``a/b`` + - element-wise divide + + * - ``a.^3`` + - ``a**3`` + - element-wise exponentiation + + * - ``(a>0.5)`` + - ``(a>0.5)`` + - matrix whose i,jth element is (a_ij > 0.5) + + * - ``find(a>0.5)`` + - ``nonzero(a>0.5)`` + - find the indices where (a > 0.5) + + * - ``a(:,find(v>0.5))`` + - ``a[:,nonzero(v>0.5)[0]]`` + - extract the columms of a where vector v > 0.5 + + * - ``a(:,find(v>0.5))`` + - ``a[:,v.T>0.5]`` + - extract the columms of a where column vector v > 0.5 + + * - ``a(a<0.5)=0`` + - ``a[a<0.5]=0`` + - a with elements less than 0.5 zeroed out + + * - ``a .* (a>0.5)`` + - ``a * (a>0.5)`` + - a with elements less than 0.5 zeroed out + + * - ``a(:) = 3`` + - ``a[:] = 3`` + - set all values to the same scalar value + + * - ``y=x`` + - ``y = x.copy()`` + - numpy assigns by reference + + * - ``y=x(2,:)`` + - ``y = x[1,:].copy()`` + - numpy slices are by reference + + * - ``y=x(:)`` + - ``y = x.flatten(1)`` + - turn array into vector (note that this forces a copy) + + * - ``1:10`` + - ``arange(1.,11.)`` or ``r_[1.:11.]`` or ``r_[1:10:10j]`` + - create an increasing vector (see note :ref:`RANGES <numpy-for-matlab-users.notes>`) + + * - ``0:9`` + - ``arange(10.)`` or ``r_[:10.]`` or ``r_[:9:10j]`` + - create an increasing vector (see note :ref:`RANGES <numpy-for-matlab-users.notes>`) + + * - ``[1:10]'`` + - ``arange(1.,11.)[:, newaxis]`` + - create a column vector + + * - ``zeros(3,4)`` + - ``zeros((3,4))`` + - 3x4 rank-2 array full of 64-bit floating point zeros + + * - ``zeros(3,4,5)`` + - ``zeros((3,4,5))`` + - 3x4x5 rank-3 array full of 64-bit floating point zeros + + * - ``ones(3,4)`` + - ``ones((3,4))`` + - 3x4 rank-2 array full of 64-bit floating point ones + + * - ``eye(3)`` + - ``eye(3)`` + - 3x3 identity matrix + + * - ``diag(a)`` + - ``diag(a)`` + - vector of diagonal elements of a + + * - ``diag(a,0)`` + - ``diag(a,0)`` + - square diagonal matrix whose nonzero values are the elements of a + + * - ``rand(3,4)`` + - ``random.rand(3,4)`` + - random 3x4 matrix + + * - ``linspace(1,3,4)`` + - ``linspace(1,3,4)`` + - 4 equally spaced samples between 1 and 3, inclusive + + * - ``[x,y]=meshgrid(0:8,0:5)`` + - ``mgrid[0:9.,0:6.]`` or ``meshgrid(r_[0:9.],r_[0:6.]`` + - two 2D arrays: one of x values, the other of y values + + * - + - ``ogrid[0:9.,0:6.]`` or ``ix_(r_[0:9.],r_[0:6.]`` + - the best way to eval functions on a grid + + * - ``[x,y]=meshgrid([1,2,4],[2,4,5])`` + - ``meshgrid([1,2,4],[2,4,5])`` + - + + * - + - ``ix_([1,2,4],[2,4,5])`` + - the best way to eval functions on a grid + + * - ``repmat(a, m, n)`` + - ``tile(a, (m, n))`` + - create m by n copies of a + + * - ``[a b]`` + - ``concatenate((a,b),1)`` or ``hstack((a,b))`` or ``column_stack((a,b))`` or ``c_[a,b]`` + - concatenate columns of ``a`` and ``b`` + + * - ``[a; b]`` + - ``concatenate((a,b))`` or ``vstack((a,b))`` or ``r_[a,b]`` + - concatenate rows of a and b + + * - ``max(max(a))`` + - ``a.max()`` + - maximum element of a (with ndims(a)<=2 for matlab) + + * - ``max(a)`` + - ``a.max(0)`` + - maximum element of each column of matrix a + + * - ``max(a,[],2)`` + - ``a.max(1)`` + - maximum element of each row of matrix a + + * - ``max(a,b)`` + - ``maximum(a, b)`` + - compares a and b element-wise, and returns the maximum value from each pair + + * - ``norm(v)`` + - ``sqrt(dot(v,v))`` or ``np.linalg.norm(v)`` + - L2 norm of vector v + + * - ``a & b`` + - ``logical_and(a,b)`` + - element-by-element AND operator (Numpy ufunc) :ref:`See note LOGICOPS <numpy-for-matlab-users.notes>` + + * - ``a | b`` + - ``logical_or(a,b)`` + - element-by-element OR operator (Numpy ufunc) :ref:`See note LOGICOPS <numpy-for-matlab-users.notes>` + + * - ``bitand(a,b)`` + - ``a & b`` + - bitwise AND operator (Python native and Numpy ufunc) + + * - ``bitor(a,b)`` + - ``a | b`` + - bitwise OR operator (Python native and Numpy ufunc) + + * - ``inv(a)`` + - ``linalg.inv(a)`` + - inverse of square matrix a + + * - ``pinv(a)`` + - ``linalg.pinv(a)`` + - pseudo-inverse of matrix a + + * - ``rank(a)`` + - ``linalg.matrix_rank(a)`` + - rank of a matrix a + + * - ``a\b`` + - ``linalg.solve(a,b)`` if ``a`` is square; ``linalg.lstsq(a,b)`` otherwise + - solution of a x = b for x + + * - ``b/a`` + - Solve a.T x.T = b.T instead + - solution of x a = b for x + + * - ``[U,S,V]=svd(a)`` + - ``U, S, Vh = linalg.svd(a), V = Vh.T`` + - singular value decomposition of a + + * - ``chol(a)`` + - ``linalg.cholesky(a).T`` + - cholesky factorization of a matrix (chol(a) in matlab returns an upper triangular matrix, but linalg.cholesky(a) returns a lower triangular matrix) + + * - ``[V,D]=eig(a)`` + - ``D,V = linalg.eig(a)`` + - eigenvalues and eigenvectors of a + + * - ``[V,D]=eig(a,b)`` + - ``V,D = np.linalg.eig(a,b)`` + - eigenvalues and eigenvectors of a,b + + * - ``[V,D]=eigs(a,k)`` + - + - find the k largest eigenvalues and eigenvectors of a + + * - ``[Q,R,P]=qr(a,0)`` + - ``Q,R = scipy.linalg.qr(a)`` + - QR decomposition + + * - ``[L,U,P]=lu(a)`` + - ``L,U = scipy.linalg.lu(a)`` or ``LU,P=scipy.linalg.lu_factor(a)`` + - LU decomposition (note: P(Matlab) == transpose(P(numpy)) ) + + * - ``conjgrad`` + - ``scipy.sparse.linalg.cg`` + - Conjugate gradients solver + + * - ``fft(a)`` + - ``fft(a)`` + - Fourier transform of a + + * - ``ifft(a)`` + - ``ifft(a)`` + - inverse Fourier transform of a + + * - ``sort(a)`` + - ``sort(a)`` or ``a.sort()`` + - sort the matrix + + * - ``[b,I] = sortrows(a,i)`` + - ``I = argsort(a[:,i]), b=a[I,:]`` + - sort the rows of the matrix + + * - ``regress(y,X)`` + - ``linalg.lstsq(X,y)`` + - multilinear regression + + * - ``decimate(x, q)`` + - ``scipy.signal.resample(x, len(x)/q)`` + - downsample with low-pass filtering + + * - ``unique(a)`` + - ``unique(a)`` + - + + * - ``squeeze(a)`` + - ``a.squeeze()`` + - + +.. _numpy-for-matlab-users.notes: + +Notes +===== + +\ **Submatrix**: Assignment to a submatrix can be done with lists of +indexes using the ``ix_`` command. E.g., for 2d array ``a``, one might +do: ``ind=[1,3]; a[np.ix_(ind,ind)]+=100``. + +\ **HELP**: There is no direct equivalent of MATLAB's ``which`` command, +but the commands ``help`` and ``source`` will usually list the filename +where the function is located. Python also has an ``inspect`` module (do +``import inspect``) which provides a ``getfile`` that often works. + +\ **INDEXING**: MATLAB® uses one based indexing, so the initial element +of a sequence has index 1. Python uses zero based indexing, so the +initial element of a sequence has index 0. Confusion and flamewars arise +because each has advantages and disadvantages. One based indexing is +consistent with common human language usage, where the "first" element +of a sequence has index 1. Zero based indexing `simplifies +indexing <http://groups.google.com/group/comp.lang.python/msg/1bf4d925dfbf368?q=g:thl3498076713d&hl=en>`__. +See also `a text by prof.dr. Edsger W. +Dijkstra <http://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html>`__. + +\ **RANGES**: In MATLAB®, ``0:5`` can be used as both a range literal +and a 'slice' index (inside parentheses); however, in Python, constructs +like ``0:5`` can *only* be used as a slice index (inside square +brackets). Thus the somewhat quirky ``r_`` object was created to allow +numpy to have a similarly terse range construction mechanism. Note that +``r_`` is not called like a function or a constructor, but rather +*indexed* using square brackets, which allows the use of Python's slice +syntax in the arguments. + +\ **LOGICOPS**: & or \| in Numpy is bitwise AND/OR, while in Matlab & +and \| are logical AND/OR. The difference should be clear to anyone with +significant programming experience. The two can appear to work the same, +but there are important differences. If you would have used Matlab's & +or \| operators, you should use the Numpy ufuncs +logical\_and/logical\_or. The notable differences between Matlab's and +Numpy's & and \| operators are: + +- Non-logical {0,1} inputs: Numpy's output is the bitwise AND of the + inputs. Matlab treats any non-zero value as 1 and returns the logical + AND. For example (3 & 4) in Numpy is 0, while in Matlab both 3 and 4 + are considered logical true and (3 & 4) returns 1. +- Precedence: Numpy's & operator is higher precedence than logical + operators like < and >; Matlab's is the reverse. + +If you know you have boolean arguments, you can get away with using +Numpy's bitwise operators, but be careful with parentheses, like this: z += (x > 1) & (x < 2). The absence of Numpy operator forms of logical\_and +and logical\_or is an unfortunate consequence of Python's design. + +**RESHAPE and LINEAR INDEXING**: Matlab always allows multi-dimensional +arrays to be accessed using scalar or linear indices, Numpy does not. +Linear indices are common in Matlab programs, e.g. find() on a matrix +returns them, whereas Numpy's find behaves differently. When converting +Matlab code it might be necessary to first reshape a matrix to a linear +sequence, perform some indexing operations and then reshape back. As +reshape (usually) produces views onto the same storage, it should be +possible to do this fairly efficiently. Note that the scan order used by +reshape in Numpy defaults to the 'C' order, whereas Matlab uses the +Fortran order. If you are simply converting to a linear sequence and +back this doesn't matter. But if you are converting reshapes from Matlab +code which relies on the scan order, then this Matlab code: z = +reshape(x,3,4); should become z = x.reshape(3,4,order='F').copy() in +Numpy. + +Customizing Your Environment +============================ + +In MATLAB® the main tool available to you for customizing the +environment is to modify the search path with the locations of your +favorite functions. You can put such customizations into a startup +script that MATLAB will run on startup. + +NumPy, or rather Python, has similar facilities. + +- To modify your Python search path to include the locations of your + own modules, define the ``PYTHONPATH`` environment variable. +- To have a particular script file executed when the interactive Python + interpreter is started, define the ``PYTHONSTARTUP`` environment + variable to contain the name of your startup script. + +Unlike MATLAB®, where anything on your path can be called immediately, +with Python you need to first do an 'import' statement to make functions +in a particular file accessible. + +For example you might make a startup script that looks like this (Note: +this is just an example, not a statement of "best practices"): + +:: + + # Make all numpy available via shorter 'num' prefix + import numpy as num + # Make all matlib functions accessible at the top level via M.func() + import numpy.matlib as M + # Make some matlib functions accessible directly at the top level via, e.g. rand(3,3) + from numpy.matlib import rand,zeros,ones,empty,eye + # Define a Hermitian function + def hermitian(A, **kwargs): + return num.transpose(A,**kwargs).conj() + # Make some shorcuts for transpose,hermitian: + # num.transpose(A) --> T(A) + # hermitian(A) --> H(A) + T = num.transpose + H = hermitian + +Links +===== + +See http://mathesaurus.sf.net/ for another MATLAB®/NumPy +cross-reference. + +An extensive list of tools for scientific work with python can be +found in the `topical software page <http://scipy.org/topical-software.html>`__. + +MATLAB® and SimuLink® are registered trademarks of The MathWorks. diff --git a/doc/source/user/performance.rst b/doc/source/user/performance.rst deleted file mode 100644 index 59f8a2edc..000000000 --- a/doc/source/user/performance.rst +++ /dev/null @@ -1,5 +0,0 @@ -*********** -Performance -*********** - -.. automodule:: numpy.doc.performance diff --git a/doc/source/user/quickstart.rst b/doc/source/user/quickstart.rst new file mode 100644 index 000000000..b636b5984 --- /dev/null +++ b/doc/source/user/quickstart.rst @@ -0,0 +1,1414 @@ +=================== +Quickstart tutorial +=================== + +.. currentmodule:: numpy + +.. testsetup:: + + import numpy as np + np.random.seed(1) + +Prerequisites +============= + +Before reading this tutorial you should know a bit of Python. If you +would like to refresh your memory, take a look at the `Python +tutorial <http://docs.python.org/tut/>`__. + +If you wish to work the examples in this tutorial, you must also have +some software installed on your computer. Please see +http://scipy.org/install.html for instructions. + +The Basics +========== + +NumPy's main object is the homogeneous multidimensional array. It is a +table of elements (usually numbers), all of the same type, indexed by a +tuple of positive integers. In Numpy dimensions are called *axes*. The +number of axes is *rank*. + +For example, the coordinates of a point in 3D space ``[1, 2, 1]`` is an +array of rank 1, because it has one axis. That axis has a length of 3. +In example pictured below, the array has rank 2 (it is 2-dimensional). +The first dimension (axis) has a length of 2, the second dimension has a +length of 3. + +:: + + [[ 1., 0., 0.], + [ 0., 1., 2.]] + +Numpy's array class is called ``ndarray``. It is also known by the alias +``array``. Note that ``numpy.array`` is not the same as the Standard +Python Library class ``array.array``, which only handles one-dimensional +arrays and offers less functionality. The more important attributes of +an ``ndarray`` object are: + +ndarray.ndim + the number of axes (dimensions) of the array. In the Python world, + the number of dimensions is referred to as *rank*. +ndarray.shape + the dimensions of the array. This is a tuple of integers indicating + the size of the array in each dimension. For a matrix with *n* rows + and *m* columns, ``shape`` will be ``(n,m)``. The length of the + ``shape`` tuple is therefore the rank, or number of dimensions, + ``ndim``. +ndarray.size + the total number of elements of the array. This is equal to the + product of the elements of ``shape``. +ndarray.dtype + an object describing the type of the elements in the array. One can + create or specify dtype's using standard Python types. Additionally + NumPy provides types of its own. numpy.int32, numpy.int16, and + numpy.float64 are some examples. +ndarray.itemsize + the size in bytes of each element of the array. For example, an + array of elements of type ``float64`` has ``itemsize`` 8 (=64/8), + while one of type ``complex32`` has ``itemsize`` 4 (=32/8). It is + equivalent to ``ndarray.dtype.itemsize``. +ndarray.data + the buffer containing the actual elements of the array. Normally, we + won't need to use this attribute because we will access the elements + in an array using indexing facilities. + +An example +---------- + + >>> import numpy as np + >>> a = np.arange(15).reshape(3, 5) + >>> a + array([[ 0, 1, 2, 3, 4], + [ 5, 6, 7, 8, 9], + [10, 11, 12, 13, 14]]) + >>> a.shape + (3, 5) + >>> a.ndim + 2 + >>> a.dtype.name + 'int64' + >>> a.itemsize + 8 + >>> a.size + 15 + >>> type(a) + <type 'numpy.ndarray'> + >>> b = np.array([6, 7, 8]) + >>> b + array([6, 7, 8]) + >>> type(b) + <type 'numpy.ndarray'> + + +Array Creation +-------------- + +There are several ways to create arrays. + +For example, you can create an array from a regular Python list or tuple +using the ``array`` function. The type of the resulting array is deduced +from the type of the elements in the sequences. + + >>> import numpy as np + >>> a = np.array([2,3,4]) + >>> a + array([2, 3, 4]) + >>> a.dtype + dtype('int64') + >>> b = np.array([1.2, 3.5, 5.1]) + >>> b.dtype + dtype('float64') + +A frequent error consists in calling ``array`` with multiple numeric +arguments, rather than providing a single list of numbers as an +argument. + +:: + + >>> a = np.array(1,2,3,4) # WRONG + >>> a = np.array([1,2,3,4]) # RIGHT + +``array`` transforms sequences of sequences into two-dimensional arrays, +sequences of sequences of sequences into three-dimensional arrays, and +so on. + + >>> b = np.array([(1.5,2,3), (4,5,6)]) + >>> b + array([[ 1.5, 2. , 3. ], + [ 4. , 5. , 6. ]]) + +The type of the array can also be explicitly specified at creation time: + +:: + + >>> c = np.array( [ [1,2], [3,4] ], dtype=complex ) + >>> c + array([[ 1.+0.j, 2.+0.j], + [ 3.+0.j, 4.+0.j]]) + +Often, the elements of an array are originally unknown, but its size is +known. Hence, NumPy offers several functions to create +arrays with initial placeholder content. These minimize the necessity of +growing arrays, an expensive operation. + +The function ``zeros`` creates an array full of zeros, the function +``ones`` creates an array full of ones, and the function ``empty`` +creates an array whose initial content is random and depends on the +state of the memory. By default, the dtype of the created array is +``float64``. + + >>> np.zeros( (3,4) ) + array([[ 0., 0., 0., 0.], + [ 0., 0., 0., 0.], + [ 0., 0., 0., 0.]]) + >>> np.ones( (2,3,4), dtype=np.int16 ) # dtype can also be specified + array([[[ 1, 1, 1, 1], + [ 1, 1, 1, 1], + [ 1, 1, 1, 1]], + [[ 1, 1, 1, 1], + [ 1, 1, 1, 1], + [ 1, 1, 1, 1]]], dtype=int16) + >>> np.empty( (2,3) ) # uninitialized, output may vary + array([[ 3.73603959e-262, 6.02658058e-154, 6.55490914e-260], + [ 5.30498948e-313, 3.14673309e-307, 1.00000000e+000]]) + +To create sequences of numbers, NumPy provides a function analogous to +``range`` that returns arrays instead of lists + + >>> np.arange( 10, 30, 5 ) + array([10, 15, 20, 25]) + >>> np.arange( 0, 2, 0.3 ) # it accepts float arguments + array([ 0. , 0.3, 0.6, 0.9, 1.2, 1.5, 1.8]) + +When ``arange`` is used with floating point arguments, it is generally +not possible to predict the number of elements obtained, due to the +finite floating point precision. For this reason, it is usually better +to use the function ``linspace`` that receives as an argument the number +of elements that we want, instead of the step: + + >>> from numpy import pi + >>> np.linspace( 0, 2, 9 ) # 9 numbers from 0 to 2 + array([ 0. , 0.25, 0.5 , 0.75, 1. , 1.25, 1.5 , 1.75, 2. ]) + >>> x = np.linspace( 0, 2*pi, 100 ) # useful to evaluate function at lots of points + >>> f = np.sin(x) + +.. seealso:: + `array`, + `zeros`, + `zeros_like`, + `ones`, + `ones_like`, + `empty`, + `empty_like`, + `arange`, + `linspace`, + `numpy.random.rand`, + `numpy.random.randn`, + `fromfunction`, + `fromfile` + +Printing Arrays +--------------- + +When you print an array, NumPy displays it in a similar way to nested +lists, but with the following layout: + +- the last axis is printed from left to right, +- the second-to-last is printed from top to bottom, +- the rest are also printed from top to bottom, with each slice + separated from the next by an empty line. + +One-dimensional arrays are then printed as rows, bidimensionals as +matrices and tridimensionals as lists of matrices. + + >>> a = np.arange(6) # 1d array + >>> print(a) + [0 1 2 3 4 5] + >>> + >>> b = np.arange(12).reshape(4,3) # 2d array + >>> print(b) + [[ 0 1 2] + [ 3 4 5] + [ 6 7 8] + [ 9 10 11]] + >>> + >>> c = np.arange(24).reshape(2,3,4) # 3d array + >>> print(c) + [[[ 0 1 2 3] + [ 4 5 6 7] + [ 8 9 10 11]] + [[12 13 14 15] + [16 17 18 19] + [20 21 22 23]]] + +See :ref:`below <quickstart.shape-manipulation>` to get +more details on ``reshape``. + +If an array is too large to be printed, NumPy automatically skips the +central part of the array and only prints the corners: + + >>> print(np.arange(10000)) + [ 0 1 2 ..., 9997 9998 9999] + >>> + >>> print(np.arange(10000).reshape(100,100)) + [[ 0 1 2 ..., 97 98 99] + [ 100 101 102 ..., 197 198 199] + [ 200 201 202 ..., 297 298 299] + ..., + [9700 9701 9702 ..., 9797 9798 9799] + [9800 9801 9802 ..., 9897 9898 9899] + [9900 9901 9902 ..., 9997 9998 9999]] + +To disable this behaviour and force NumPy to print the entire array, you +can change the printing options using ``set_printoptions``. + +:: + + >>> np.set_printoptions(threshold='nan') + + +Basic Operations +---------------- + +Arithmetic operators on arrays apply *elementwise*. A new array is +created and filled with the result. + + >>> a = np.array( [20,30,40,50] ) + >>> b = np.arange( 4 ) + >>> b + array([0, 1, 2, 3]) + >>> c = a-b + >>> c + array([20, 29, 38, 47]) + >>> b**2 + array([0, 1, 4, 9]) + >>> 10*np.sin(a) + array([ 9.12945251, -9.88031624, 7.4511316 , -2.62374854]) + >>> a<35 + array([ True, True, False, False], dtype=bool) + +Unlike in many matrix languages, the product operator ``*`` operates +elementwise in NumPy arrays. The matrix product can be performed using +the ``dot`` function or method: + + >>> A = np.array( [[1,1], + ... [0,1]] ) + >>> B = np.array( [[2,0], + ... [3,4]] ) + >>> A*B # elementwise product + array([[2, 0], + [0, 4]]) + >>> A.dot(B) # matrix product + array([[5, 4], + [3, 4]]) + >>> np.dot(A, B) # another matrix product + array([[5, 4], + [3, 4]]) + +Some operations, such as ``+=`` and ``*=``, act in place to modify an +existing array rather than create a new one. + + >>> a = np.ones((2,3), dtype=int) + >>> b = np.random.random((2,3)) + >>> a *= 3 + >>> a + array([[3, 3, 3], + [3, 3, 3]]) + >>> b += a + >>> b + array([[ 3.417022 , 3.72032449, 3.00011437], + [ 3.30233257, 3.14675589, 3.09233859]]) + >>> a += b # b is not automatically converted to integer type + Traceback (most recent call last): + ... + TypeError: Cannot cast ufunc add output from dtype('float64') to dtype('int64') with casting rule 'same_kind' + +When operating with arrays of different types, the type of the resulting +array corresponds to the more general or precise one (a behavior known +as upcasting). + + >>> a = np.ones(3, dtype=np.int32) + >>> b = np.linspace(0,pi,3) + >>> b.dtype.name + 'float64' + >>> c = a+b + >>> c + array([ 1. , 2.57079633, 4.14159265]) + >>> c.dtype.name + 'float64' + >>> d = np.exp(c*1j) + >>> d + array([ 0.54030231+0.84147098j, -0.84147098+0.54030231j, + -0.54030231-0.84147098j]) + >>> d.dtype.name + 'complex128' + +Many unary operations, such as computing the sum of all the elements in +the array, are implemented as methods of the ``ndarray`` class. + + >>> a = np.random.random((2,3)) + >>> a + array([[ 0.18626021, 0.34556073, 0.39676747], + [ 0.53881673, 0.41919451, 0.6852195 ]]) + >>> a.sum() + 2.5718191614547998 + >>> a.min() + 0.1862602113776709 + >>> a.max() + 0.6852195003967595 + +By default, these operations apply to the array as though it were a list +of numbers, regardless of its shape. However, by specifying the ``axis`` +parameter you can apply an operation along the specified axis of an +array: + + >>> b = np.arange(12).reshape(3,4) + >>> b + array([[ 0, 1, 2, 3], + [ 4, 5, 6, 7], + [ 8, 9, 10, 11]]) + >>> + >>> b.sum(axis=0) # sum of each column + array([12, 15, 18, 21]) + >>> + >>> b.min(axis=1) # min of each row + array([0, 4, 8]) + >>> + >>> b.cumsum(axis=1) # cumulative sum along each row + array([[ 0, 1, 3, 6], + [ 4, 9, 15, 22], + [ 8, 17, 27, 38]]) + + +Universal Functions +------------------- + +NumPy provides familiar mathematical functions such as sin, cos, and +exp. In NumPy, these are called "universal +functions"(\ ``ufunc``). Within NumPy, these functions +operate elementwise on an array, producing an array as output. + + >>> B = np.arange(3) + >>> B + array([0, 1, 2]) + >>> np.exp(B) + array([ 1. , 2.71828183, 7.3890561 ]) + >>> np.sqrt(B) + array([ 0. , 1. , 1.41421356]) + >>> C = np.array([2., -1., 4.]) + >>> np.add(B, C) + array([ 2., 0., 6.]) + +.. seealso:: + + `all`, + `any`, + `apply_along_axis`, + `argmax`, + `argmin`, + `argsort`, + `average`, + `bincount`, + `ceil`, + `clip`, + `conj`, + `corrcoef`, + `cov`, + `cross`, + `cumprod`, + `cumsum`, + `diff`, + `dot`, + `floor`, + `inner`, + `inv`, + `lexsort`, + `max`, + `maximum`, + `mean`, + `median`, + `min`, + `minimum`, + `nonzero`, + `outer`, + `prod`, + `re`, + `round`, + `sort`, + `std`, + `sum`, + `trace`, + `transpose`, + `var`, + `vdot`, + `vectorize`, + `where` + +Indexing, Slicing and Iterating +------------------------------- + +**One-dimensional** arrays can be indexed, sliced and iterated over, +much like +`lists <https://docs.python.org/tutorial/introduction.html#lists>`__ +and other Python sequences. + + >>> a = np.arange(10)**3 + >>> a + array([ 0, 1, 8, 27, 64, 125, 216, 343, 512, 729]) + >>> a[2] + 8 + >>> a[2:5] + array([ 8, 27, 64]) + >>> a[:6:2] = -1000 # equivalent to a[0:6:2] = -1000; from start to position 6, exclusive, set every 2nd element to -1000 + >>> a + array([-1000, 1, -1000, 27, -1000, 125, 216, 343, 512, 729]) + >>> a[ : :-1] # reversed a + array([ 729, 512, 343, 216, 125, -1000, 27, -1000, 1, -1000]) + >>> for i in a: + ... print(i**(1/3.)) + ... + nan + 1.0 + nan + 3.0 + nan + 5.0 + 6.0 + 7.0 + 8.0 + 9.0 + +**Multidimensional** arrays can have one index per axis. These indices +are given in a tuple separated by commas: + + >>> def f(x,y): + ... return 10*x+y + ... + >>> b = np.fromfunction(f,(5,4),dtype=int) + >>> b + array([[ 0, 1, 2, 3], + [10, 11, 12, 13], + [20, 21, 22, 23], + [30, 31, 32, 33], + [40, 41, 42, 43]]) + >>> b[2,3] + 23 + >>> b[0:5, 1] # each row in the second column of b + array([ 1, 11, 21, 31, 41]) + >>> b[ : ,1] # equivalent to the previous example + array([ 1, 11, 21, 31, 41]) + >>> b[1:3, : ] # each column in the second and third row of b + array([[10, 11, 12, 13], + [20, 21, 22, 23]]) + +When fewer indices are provided than the number of axes, the missing +indices are considered complete slices\ ``:`` + + >>> b[-1] # the last row. Equivalent to b[-1,:] + array([40, 41, 42, 43]) + +The expression within brackets in ``b[i]`` is treated as an ``i`` +followed by as many instances of ``:`` as needed to represent the +remaining axes. NumPy also allows you to write this using dots as +``b[i,...]``. + +The **dots** (``...``) represent as many colons as needed to produce a +complete indexing tuple. For example, if ``x`` is a rank 5 array (i.e., +it has 5 axes), then + +- ``x[1,2,...]`` is equivalent to ``x[1,2,:,:,:]``, +- ``x[...,3]`` to ``x[:,:,:,:,3]`` and +- ``x[4,...,5,:]`` to ``x[4,:,:,5,:]``. + + >>> c = np.array( [[[ 0, 1, 2], # a 3D array (two stacked 2D arrays) + ... [ 10, 12, 13]], + ... [[100,101,102], + ... [110,112,113]]]) + >>> c.shape + (2, 2, 3) + >>> c[1,...] # same as c[1,:,:] or c[1] + array([[100, 101, 102], + [110, 112, 113]]) + >>> c[...,2] # same as c[:,:,2] + array([[ 2, 13], + [102, 113]]) + +**Iterating** over multidimensional arrays is done with respect to the +first axis: + + >>> for row in b: + ... print(row) + ... + [0 1 2 3] + [10 11 12 13] + [20 21 22 23] + [30 31 32 33] + [40 41 42 43] + +However, if one wants to perform an operation on each element in the +array, one can use the ``flat`` attribute which is an +`iterator <https://docs.python.org/2/tutorial/classes.html#iterators>`__ +over all the elements of the array: + + >>> for element in b.flat: + ... print(element) + ... + 0 + 1 + 2 + 3 + 10 + 11 + 12 + 13 + 20 + 21 + 22 + 23 + 30 + 31 + 32 + 33 + 40 + 41 + 42 + 43 + +.. seealso:: + + :ref:`basics.indexing`, + :ref:`arrays.indexing` (reference), + `newaxis`, + `ndenumerate`, + `indices` + +.. _quickstart.shape-manipulation: + +Shape Manipulation +================== + +Changing the shape of an array +------------------------------ + +An array has a shape given by the number of elements along each axis: + + >>> a = np.floor(10*np.random.random((3,4))) + >>> a + array([[ 2., 8., 0., 6.], + [ 4., 5., 1., 1.], + [ 8., 9., 3., 6.]]) + >>> a.shape + (3, 4) + +The shape of an array can be changed with various commands: + + >>> a.ravel() # flatten the array + array([ 2., 8., 0., 6., 4., 5., 1., 1., 8., 9., 3., 6.]) + >>> a.shape = (6, 2) + >>> a.T + array([[ 2., 0., 4., 1., 8., 3.], + [ 8., 6., 5., 1., 9., 6.]]) + +The order of the elements in the array resulting from ravel() is +normally "C-style", that is, the rightmost index "changes the fastest", +so the element after a[0,0] is a[0,1]. If the array is reshaped to some +other shape, again the array is treated as "C-style". Numpy normally +creates arrays stored in this order, so ravel() will usually not need to +copy its argument, but if the array was made by taking slices of another +array or created with unusual options, it may need to be copied. The +functions ravel() and reshape() can also be instructed, using an +optional argument, to use FORTRAN-style arrays, in which the leftmost +index changes the fastest. + +The `reshape` function returns its +argument with a modified shape, whereas the +`ndarray.resize` method modifies the array +itself: + + >>> a + array([[ 2., 8.], + [ 0., 6.], + [ 4., 5.], + [ 1., 1.], + [ 8., 9.], + [ 3., 6.]]) + >>> a.resize((2,6)) + >>> a + array([[ 2., 8., 0., 6., 4., 5.], + [ 1., 1., 8., 9., 3., 6.]]) + +If a dimension is given as -1 in a reshaping operation, the other +dimensions are automatically calculated: + + >>> a.reshape(3,-1) + array([[ 2., 8., 0., 6.], + [ 4., 5., 1., 1.], + [ 8., 9., 3., 6.]]) + +.. seealso:: + + `ndarray.shape`, + `reshape`, + `resize`, + `ravel` + +Stacking together different arrays +---------------------------------- + +Several arrays can be stacked together along different axes: + + >>> a = np.floor(10*np.random.random((2,2))) + >>> a + array([[ 8., 8.], + [ 0., 0.]]) + >>> b = np.floor(10*np.random.random((2,2))) + >>> b + array([[ 1., 8.], + [ 0., 4.]]) + >>> np.vstack((a,b)) + array([[ 8., 8.], + [ 0., 0.], + [ 1., 8.], + [ 0., 4.]]) + >>> np.hstack((a,b)) + array([[ 8., 8., 1., 8.], + [ 0., 0., 0., 4.]]) + +The function `column_stack` +stacks 1D arrays as columns into a 2D array. It is equivalent to +`vstack` only for 1D arrays: + + >>> from numpy import newaxis + >>> np.column_stack((a,b)) # With 2D arrays + array([[ 8., 8., 1., 8.], + [ 0., 0., 0., 4.]]) + >>> a = np.array([4.,2.]) + >>> b = np.array([2.,8.]) + >>> a[:,newaxis] # This allows to have a 2D columns vector + array([[ 4.], + [ 2.]]) + >>> np.column_stack((a[:,newaxis],b[:,newaxis])) + array([[ 4., 2.], + [ 2., 8.]]) + >>> np.vstack((a[:,newaxis],b[:,newaxis])) # The behavior of vstack is different + array([[ 4.], + [ 2.], + [ 2.], + [ 8.]]) + +For arrays of with more than two dimensions, +`hstack` stacks along their second +axes, `vstack` stacks along their +first axes, and `concatenate` +allows for an optional arguments giving the number of the axis along +which the concatenation should happen. + +**Note** + +In complex cases, `r_` and +`c_` are useful for creating arrays +by stacking numbers along one axis. They allow the use of range literals +(":") : + + >>> np.r_[1:4,0,4] + array([1, 2, 3, 0, 4]) + +When used with arrays as arguments, +`r_` and +`c_` are similar to +`vstack` and +`hstack` in their default behavior, +but allow for an optional argument giving the number of the axis along +which to concatenate. + +.. seealso:: + + `hstack`, + `vstack`, + `column_stack`, + `concatenate`, + `c_`, + `r_` + +Splitting one array into several smaller ones +--------------------------------------------- + +Using `hsplit`, you can split an +array along its horizontal axis, either by specifying the number of +equally shaped arrays to return, or by specifying the columns after +which the division should occur: + + >>> a = np.floor(10*np.random.random((2,12))) + >>> a + array([[ 9., 5., 6., 3., 6., 8., 0., 7., 9., 7., 2., 7.], + [ 1., 4., 9., 2., 2., 1., 0., 6., 2., 2., 4., 0.]]) + >>> np.hsplit(a,3) # Split a into 3 + [array([[ 9., 5., 6., 3.], + [ 1., 4., 9., 2.]]), array([[ 6., 8., 0., 7.], + [ 2., 1., 0., 6.]]), array([[ 9., 7., 2., 7.], + [ 2., 2., 4., 0.]])] + >>> np.hsplit(a,(3,4)) # Split a after the third and the fourth column + [array([[ 9., 5., 6.], + [ 1., 4., 9.]]), array([[ 3.], + [ 2.]]), array([[ 6., 8., 0., 7., 9., 7., 2., 7.], + [ 2., 1., 0., 6., 2., 2., 4., 0.]])] + +`vsplit` splits along the vertical +axis, and `array_split` allows +one to specify along which axis to split. + +Copies and Views +================ + +When operating and manipulating arrays, their data is sometimes copied +into a new array and sometimes not. This is often a source of confusion +for beginners. There are three cases: + +No Copy at All +-------------- + +Simple assignments make no copy of array objects or of their data. + + >>> a = np.arange(12) + >>> b = a # no new object is created + >>> b is a # a and b are two names for the same ndarray object + True + >>> b.shape = 3,4 # changes the shape of a + >>> a.shape + (3, 4) + +Python passes mutable objects as references, so function calls make no +copy. + + >>> def f(x): + ... print(id(x)) + ... + >>> id(a) # id is a unique identifier of an object + 148293216 + >>> f(a) + 148293216 + +View or Shallow Copy +-------------------- + +Different array objects can share the same data. The ``view`` method +creates a new array object that looks at the same data. + + >>> c = a.view() + >>> c is a + False + >>> c.base is a # c is a view of the data owned by a + True + >>> c.flags.owndata + False + >>> + >>> c.shape = 2,6 # a's shape doesn't change + >>> a.shape + (3, 4) + >>> c[0,4] = 1234 # a's data changes + >>> a + array([[ 0, 1, 2, 3], + [1234, 5, 6, 7], + [ 8, 9, 10, 11]]) + +Slicing an array returns a view of it: + + >>> s = a[ : , 1:3] # spaces added for clarity; could also be written "s = a[:,1:3]" + >>> s[:] = 10 # s[:] is a view of s. Note the difference between s=10 and s[:]=10 + >>> a + array([[ 0, 10, 10, 3], + [1234, 10, 10, 7], + [ 8, 10, 10, 11]]) + + +Deep Copy +--------- + +The ``copy`` method makes a complete copy of the array and its data. + + + >>> d = a.copy() # a new array object with new data is created + >>> d is a + False + >>> d.base is a # d doesn't share anything with a + False + >>> d[0,0] = 9999 + >>> a + array([[ 0, 10, 10, 3], + [1234, 10, 10, 7], + [ 8, 10, 10, 11]]) + + +Functions and Methods Overview +------------------------------ + +Here is a list of some useful NumPy functions and methods names +ordered in categories. See :ref:`routines` for the full list. + +Array Creation + `arange`, + `array`, + `copy`, + `empty`, + `empty_like`, + `eye`, + `fromfile`, + `fromfunction`, + `identity`, + `linspace`, + `logspace`, + `mgrid`, + `ogrid`, + `ones`, + `ones_like`, + `r`, + `zeros`, + `zeros_like` +Conversions + `ndarray.astype`, + `atleast_1d`, + `atleast_2d`, + `atleast_3d`, + `mat` +Manipulations + `array_split`, + `column_stack`, + `concatenate`, + `diagonal`, + `dsplit`, + `dstack`, + `hsplit`, + `hstack`, + `ndarray.item`, + `newaxis`, + `ravel`, + `repeat`, + `reshape`, + `resize`, + `squeeze`, + `swapaxes`, + `take`, + `transpose`, + `vsplit`, + `vstack` +Questions + `all`, + `any`, + `nonzero`, + `where` +Ordering + `argmax`, + `argmin`, + `argsort`, + `max`, + `min`, + `ptp`, + `searchsorted`, + `sort` +Operations + `choose`, + `compress`, + `cumprod`, + `cumsum`, + `inner`, + `ndarray.fill`, + `imag`, + `prod`, + `put`, + `putmask`, + `real`, + `sum` +Basic Statistics + `cov`, + `mean`, + `std`, + `var` +Basic Linear Algebra + `cross`, + `dot`, + `outer`, + `linalg.svd`, + `vdot` + +Less Basic +========== + +Broadcasting rules +------------------ + +Broadcasting allows universal functions to deal in a meaningful way with +inputs that do not have exactly the same shape. + +The first rule of broadcasting is that if all input arrays do not have +the same number of dimensions, a "1" will be repeatedly prepended to the +shapes of the smaller arrays until all the arrays have the same number +of dimensions. + +The second rule of broadcasting ensures that arrays with a size of 1 +along a particular dimension act as if they had the size of the array +with the largest shape along that dimension. The value of the array +element is assumed to be the same along that dimension for the +"broadcast" array. + +After application of the broadcasting rules, the sizes of all arrays +must match. More details can be found in :doc:`basics.broadcasting`. + +Fancy indexing and index tricks +=============================== + +NumPy offers more indexing facilities than regular Python sequences. In +addition to indexing by integers and slices, as we saw before, arrays +can be indexed by arrays of integers and arrays of booleans. + +Indexing with Arrays of Indices +------------------------------- + + >>> a = np.arange(12)**2 # the first 12 square numbers + >>> i = np.array( [ 1,1,3,8,5 ] ) # an array of indices + >>> a[i] # the elements of a at the positions i + array([ 1, 1, 9, 64, 25]) + >>> + >>> j = np.array( [ [ 3, 4], [ 9, 7 ] ] ) # a bidimensional array of indices + >>> a[j] # the same shape as j + array([[ 9, 16], + [81, 49]]) + +When the indexed array ``a`` is multidimensional, a single array of +indices refers to the first dimension of ``a``. The following example +shows this behavior by converting an image of labels into a color image +using a palette. + + >>> palette = np.array( [ [0,0,0], # black + ... [255,0,0], # red + ... [0,255,0], # green + ... [0,0,255], # blue + ... [255,255,255] ] ) # white + >>> image = np.array( [ [ 0, 1, 2, 0 ], # each value corresponds to a color in the palette + ... [ 0, 3, 4, 0 ] ] ) + >>> palette[image] # the (2,4,3) color image + array([[[ 0, 0, 0], + [255, 0, 0], + [ 0, 255, 0], + [ 0, 0, 0]], + [[ 0, 0, 0], + [ 0, 0, 255], + [255, 255, 255], + [ 0, 0, 0]]]) + +We can also give indexes for more than one dimension. The arrays of +indices for each dimension must have the same shape. + + >>> a = np.arange(12).reshape(3,4) + >>> a + array([[ 0, 1, 2, 3], + [ 4, 5, 6, 7], + [ 8, 9, 10, 11]]) + >>> i = np.array( [ [0,1], # indices for the first dim of a + ... [1,2] ] ) + >>> j = np.array( [ [2,1], # indices for the second dim + ... [3,3] ] ) + >>> + >>> a[i,j] # i and j must have equal shape + array([[ 2, 5], + [ 7, 11]]) + >>> + >>> a[i,2] + array([[ 2, 6], + [ 6, 10]]) + >>> + >>> a[:,j] # i.e., a[ : , j] + array([[[ 2, 1], + [ 3, 3]], + [[ 6, 5], + [ 7, 7]], + [[10, 9], + [11, 11]]]) + +Naturally, we can put ``i`` and ``j`` in a sequence (say a list) and +then do the indexing with the list. + + >>> l = [i,j] + >>> a[l] # equivalent to a[i,j] + array([[ 2, 5], + [ 7, 11]]) + +However, we can not do this by putting ``i`` and ``j`` into an array, +because this array will be interpreted as indexing the first dimension +of a. + + >>> s = np.array( [i,j] ) + >>> a[s] # not what we want + Traceback (most recent call last): + File "<stdin>", line 1, in ? + IndexError: index (3) out of range (0<=index<=2) in dimension 0 + >>> + >>> a[tuple(s)] # same as a[i,j] + array([[ 2, 5], + [ 7, 11]]) + +Another common use of indexing with arrays is the search of the maximum +value of time-dependent series : + + >>> time = np.linspace(20, 145, 5) # time scale + >>> data = np.sin(np.arange(20)).reshape(5,4) # 4 time-dependent series + >>> time + array([ 20. , 51.25, 82.5 , 113.75, 145. ]) + >>> data + array([[ 0. , 0.84147098, 0.90929743, 0.14112001], + [-0.7568025 , -0.95892427, -0.2794155 , 0.6569866 ], + [ 0.98935825, 0.41211849, -0.54402111, -0.99999021], + [-0.53657292, 0.42016704, 0.99060736, 0.65028784], + [-0.28790332, -0.96139749, -0.75098725, 0.14987721]]) + >>> + >>> ind = data.argmax(axis=0) # index of the maxima for each series + >>> ind + array([2, 0, 3, 1]) + >>> + >>> time_max = time[ ind] # times corresponding to the maxima + >>> + >>> data_max = data[ind, xrange(data.shape[1])] # => data[ind[0],0], data[ind[1],1]... + >>> + >>> time_max + array([ 82.5 , 20. , 113.75, 51.25]) + >>> data_max + array([ 0.98935825, 0.84147098, 0.99060736, 0.6569866 ]) + >>> + >>> np.all(data_max == data.max(axis=0)) + True + +You can also use indexing with arrays as a target to assign to: + + >>> a = np.arange(5) + >>> a + array([0, 1, 2, 3, 4]) + >>> a[[1,3,4]] = 0 + >>> a + array([0, 0, 2, 0, 0]) + +However, when the list of indices contains repetitions, the assignment +is done several times, leaving behind the last value: + + >>> a = np.arange(5) + >>> a[[0,0,2]]=[1,2,3] + >>> a + array([2, 1, 3, 3, 4]) + +This is reasonable enough, but watch out if you want to use Python's +``+=`` construct, as it may not do what you expect: + + >>> a = np.arange(5) + >>> a[[0,0,2]]+=1 + >>> a + array([1, 1, 3, 3, 4]) + +Even though 0 occurs twice in the list of indices, the 0th element is +only incremented once. This is because Python requires "a+=1" to be +equivalent to "a=a+1". + +Indexing with Boolean Arrays +---------------------------- + +When we index arrays with arrays of (integer) indices we are providing +the list of indices to pick. With boolean indices the approach is +different; we explicitly choose which items in the array we want and +which ones we don't. + +The most natural way one can think of for boolean indexing is to use +boolean arrays that have *the same shape* as the original array: + + >>> a = np.arange(12).reshape(3,4) + >>> b = a > 4 + >>> b # b is a boolean with a's shape + array([[False, False, False, False], + [False, True, True, True], + [ True, True, True, True]], dtype=bool) + >>> a[b] # 1d array with the selected elements + array([ 5, 6, 7, 8, 9, 10, 11]) + +This property can be very useful in assignments: + + >>> a[b] = 0 # All elements of 'a' higher than 4 become 0 + >>> a + array([[0, 1, 2, 3], + [4, 0, 0, 0], + [0, 0, 0, 0]]) + +You can look at the following +example to see +how to use boolean indexing to generate an image of the `Mandelbrot +set <http://en.wikipedia.org/wiki/Mandelbrot_set>`__: + +.. plot:: + + >>> import numpy as np + >>> import matplotlib.pyplot as plt + >>> def mandelbrot( h,w, maxit=20 ): + ... """Returns an image of the Mandelbrot fractal of size (h,w).""" + ... y,x = np.ogrid[ -1.4:1.4:h*1j, -2:0.8:w*1j ] + ... c = x+y*1j + ... z = c + ... divtime = maxit + np.zeros(z.shape, dtype=int) + ... + ... for i in range(maxit): + ... z = z**2 + c + ... diverge = z*np.conj(z) > 2**2 # who is diverging + ... div_now = diverge & (divtime==maxit) # who is diverging now + ... divtime[div_now] = i # note when + ... z[diverge] = 2 # avoid diverging too much + ... + ... return divtime + >>> plt.imshow(mandelbrot(400,400)) + >>> plt.show() + +The second way of indexing with booleans is more similar to integer +indexing; for each dimension of the array we give a 1D boolean array +selecting the slices we want. + + >>> a = np.arange(12).reshape(3,4) + >>> b1 = np.array([False,True,True]) # first dim selection + >>> b2 = np.array([True,False,True,False]) # second dim selection + >>> + >>> a[b1,:] # selecting rows + array([[ 4, 5, 6, 7], + [ 8, 9, 10, 11]]) + >>> + >>> a[b1] # same thing + array([[ 4, 5, 6, 7], + [ 8, 9, 10, 11]]) + >>> + >>> a[:,b2] # selecting columns + array([[ 0, 2], + [ 4, 6], + [ 8, 10]]) + >>> + >>> a[b1,b2] # a weird thing to do + array([ 4, 10]) + +Note that the length of the 1D boolean array must coincide with the +length of the dimension (or axis) you want to slice. In the previous +example, ``b1`` is a 1-rank array with length 3 (the number of *rows* in +``a``), and ``b2`` (of length 4) is suitable to index the 2nd rank +(columns) of ``a``. + +The ix_() function +------------------- + +The `ix_` function can be used to combine different vectors so as to +obtain the result for each n-uplet. For example, if you want to compute +all the a+b\*c for all the triplets taken from each of the vectors a, b +and c: + + >>> a = np.array([2,3,4,5]) + >>> b = np.array([8,5,4]) + >>> c = np.array([5,4,6,8,3]) + >>> ax,bx,cx = np.ix_(a,b,c) + >>> ax + array([[[2]], + [[3]], + [[4]], + [[5]]]) + >>> bx + array([[[8], + [5], + [4]]]) + >>> cx + array([[[5, 4, 6, 8, 3]]]) + >>> ax.shape, bx.shape, cx.shape + ((4, 1, 1), (1, 3, 1), (1, 1, 5)) + >>> result = ax+bx*cx + >>> result + array([[[42, 34, 50, 66, 26], + [27, 22, 32, 42, 17], + [22, 18, 26, 34, 14]], + [[43, 35, 51, 67, 27], + [28, 23, 33, 43, 18], + [23, 19, 27, 35, 15]], + [[44, 36, 52, 68, 28], + [29, 24, 34, 44, 19], + [24, 20, 28, 36, 16]], + [[45, 37, 53, 69, 29], + [30, 25, 35, 45, 20], + [25, 21, 29, 37, 17]]]) + >>> result[3,2,4] + 17 + >>> a[3]+b[2]*c[4] + 17 + +You could also implement the reduce as follows: + + >>> def ufunc_reduce(ufct, *vectors): + ... vs = np.ix_(*vectors) + ... r = ufct.identity + ... for v in vs: + ... r = ufct(r,v) + ... return r + +and then use it as: + + >>> ufunc_reduce(np.add,a,b,c) + array([[[15, 14, 16, 18, 13], + [12, 11, 13, 15, 10], + [11, 10, 12, 14, 9]], + [[16, 15, 17, 19, 14], + [13, 12, 14, 16, 11], + [12, 11, 13, 15, 10]], + [[17, 16, 18, 20, 15], + [14, 13, 15, 17, 12], + [13, 12, 14, 16, 11]], + [[18, 17, 19, 21, 16], + [15, 14, 16, 18, 13], + [14, 13, 15, 17, 12]]]) + +The advantage of this version of reduce compared to the normal +ufunc.reduce is that it makes use of the `Broadcasting +Rules <Tentative_NumPy_Tutorial.html#head-c43f3f81719d84f09ae2b33a22eaf50b26333db8>`__ +in order to avoid creating an argument array the size of the output +times the number of vectors. + +Indexing with strings +--------------------- + +See `RecordArrays <RecordArrays.html>`__. + +Linear Algebra +============== + +Work in progress. Basic linear algebra to be included here. + +Simple Array Operations +----------------------- + +See linalg.py in numpy folder for more. + + >>> import numpy as np + >>> a = np.array([[1.0, 2.0], [3.0, 4.0]]) + >>> print(a) + [[ 1. 2.] + [ 3. 4.]] + + >>> a.transpose() + array([[ 1., 3.], + [ 2., 4.]]) + + >>> np.linalg.inv(a) + array([[-2. , 1. ], + [ 1.5, -0.5]]) + + >>> u = np.eye(2) # unit 2x2 matrix; "eye" represents "I" + >>> u + array([[ 1., 0.], + [ 0., 1.]]) + >>> j = np.array([[0.0, -1.0], [1.0, 0.0]]) + + >>> np.dot (j, j) # matrix product + array([[-1., 0.], + [ 0., -1.]]) + + >>> np.trace(u) # trace + 2.0 + + >>> y = np.array([[5.], [7.]]) + >>> np.linalg.solve(a, y) + array([[-3.], + [ 4.]]) + + >>> np.linalg.eig(j) + (array([ 0.+1.j, 0.-1.j]), array([[ 0.70710678+0.j , 0.70710678-0.j ], + [ 0.00000000-0.70710678j, 0.00000000+0.70710678j]])) + +:: + + Parameters: + square matrix + Returns + The eigenvalues, each repeated according to its multiplicity. + The normalized (unit "length") eigenvectors, such that the + column ``v[:,i]`` is the eigenvector corresponding to the + eigenvalue ``w[i]`` . + +Tricks and Tips +=============== + +Here we give a list of short and useful tips. + +"Automatic" Reshaping +--------------------- + +To change the dimensions of an array, you can omit one of the sizes +which will then be deduced automatically: + + >>> a = np.arange(30) + >>> a.shape = 2,-1,3 # -1 means "whatever is needed" + >>> a.shape + (2, 5, 3) + >>> a + array([[[ 0, 1, 2], + [ 3, 4, 5], + [ 6, 7, 8], + [ 9, 10, 11], + [12, 13, 14]], + [[15, 16, 17], + [18, 19, 20], + [21, 22, 23], + [24, 25, 26], + [27, 28, 29]]]) + +Vector Stacking +--------------- + +How do we construct a 2D array from a list of equally-sized row vectors? +In MATLAB this is quite easy: if ``x`` and ``y`` are two vectors of the +same length you only need do ``m=[x;y]``. In NumPy this works via the +functions ``column_stack``, ``dstack``, ``hstack`` and ``vstack``, +depending on the dimension in which the stacking is to be done. For +example: + +:: + + x = np.arange(0,10,2) # x=([0,2,4,6,8]) + y = np.arange(5) # y=([0,1,2,3,4]) + m = np.vstack([x,y]) # m=([[0,2,4,6,8], + # [0,1,2,3,4]]) + xy = np.hstack([x,y]) # xy =([0,2,4,6,8,0,1,2,3,4]) + +The logic behind those functions in more than two dimensions can be +strange. + +.. seealso:: + + :doc:`numpy-for-matlab-users` + +Histograms +---------- + +The NumPy ``histogram`` function applied to an array returns a pair of +vectors: the histogram of the array and the vector of bins. Beware: +``matplotlib`` also has a function to build histograms (called ``hist``, +as in Matlab) that differs from the one in NumPy. The main difference is +that ``pylab.hist`` plots the histogram automatically, while +``numpy.histogram`` only generates the data. + +.. plot:: + + >>> import numpy as np + >>> import matplotlib.pyplot as plt + >>> # Build a vector of 10000 normal deviates with variance 0.5^2 and mean 2 + >>> mu, sigma = 2, 0.5 + >>> v = np.random.normal(mu,sigma,10000) + >>> # Plot a normalized histogram with 50 bins + >>> plt.hist(v, bins=50, normed=1) # matplotlib version (plot) + >>> plt.show() + >>> # Compute the histogram with numpy and then plot it + >>> (n, bins) = np.histogram(v, bins=50, normed=True) # NumPy version (no plot) + >>> plt.plot(.5*(bins[1:]+bins[:-1]), n) + >>> plt.show() + + +Further reading +=============== + +- The `Python tutorial <http://docs.python.org/tutorial/>`__ +- :ref:`reference` +- `SciPy Tutorial <https://docs.scipy.org/doc/scipy/reference/tutorial/index.html>`__ +- `SciPy Lecture Notes <http://www.scipy-lectures.org>`__ +- A `matlab, R, IDL, NumPy/SciPy dictionary <http://mathesaurus.sf.net/>`__ diff --git a/doc/source/user/setting-up.rst b/doc/source/user/setting-up.rst new file mode 100644 index 000000000..f70dacf82 --- /dev/null +++ b/doc/source/user/setting-up.rst @@ -0,0 +1,9 @@ +********** +Setting up +********** + +.. toctree:: + :maxdepth: 1 + + whatisnumpy + install |