summaryrefslogtreecommitdiff
path: root/PVCM/cama/fr/ma1 np03 Manipulations.ipynb
diff options
context:
space:
mode:
Diffstat (limited to 'PVCM/cama/fr/ma1 np03 Manipulations.ipynb')
-rw-r--r--PVCM/cama/fr/ma1 np03 Manipulations.ipynb823
1 files changed, 823 insertions, 0 deletions
diff --git a/PVCM/cama/fr/ma1 np03 Manipulations.ipynb b/PVCM/cama/fr/ma1 np03 Manipulations.ipynb
new file mode 100644
index 0000000..b676e65
--- /dev/null
+++ b/PVCM/cama/fr/ma1 np03 Manipulations.ipynb
@@ -0,0 +1,823 @@
+{
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8.10"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2,
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "lang": "fr"
+ },
+ "source": [
+ "Les [manipulations d'un tableau](https://docs.scipy.org/doc/numpy-1.15.1/reference/routines.array-manipulation.html) comprennent :\n",
+ "\n",
+ "* la réorganisation du tableau (réindexation) \n",
+ "* l'aggrégation de 2 tableaux ou plus\n",
+ "* le découpage d'un tableau en 2 ou plus\n",
+ "\n",
+ "Avant de regarder ces points, regardons comment Numpy présente les\n",
+ "dimensions d'un tableau multidimensionnel avec la notion d'axes."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(2, 4, 3)"
+ ]
+ },
+ "execution_count": 1,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import numpy as np\n",
+ "\n",
+ "# An array of marks of 3 exams for 4 students in two subjects \n",
+ "# (therefore 6 marks per students or 12 per subjects)\n",
+ "\n",
+ "# stud.1 stud.2 stud.3 stud.4\n",
+ "marks = np.array([[[7,13,11], [7,7,13], [5,9,11], [7,17,15]], # subject 1\n",
+ " [[8,12,14], [8,12,12], [8,12,10], [12,16,12]]]) # subject 2\n",
+ "marks.shape"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "lang": "fr"
+ },
+ "source": [
+ "## Les axes\n",
+ "\n",
+ "Un tableau a des axes qui correspondent aux axes d'un repère dans l'espace. L'ordre des axes\n",
+ "est celui de l'inclusion des crochets. En 2D un tableau de tableau est un tableau de lignes avec\n",
+ "chaque ligne qui est un tableau 1D de valeurs. L'ordre est donc lignes puis colonnes (contrairement à l'axes $(x,y)$ dans\n",
+ "l'espace). En 3D l'ordre est ligne, colonne, profondeur si on désire avoir une image, sinon c'est 0, 1 et 2.\n",
+ "\n",
+ "De très nombreuses opérations sur les tableaux se font suivant un des axes du tableau aussi il est important de \n",
+ "comprendre ce que sont les axes.\n",
+ "\n",
+ "Regardons l'exemple des notes ci-dessus. Les axes sont\n",
+ "\n",
+ "0. les matières\n",
+ "1. les étudiants \n",
+ "2. les examens"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "lang": "fr"
+ },
+ "source": [
+ "Faire la moyenne des valeurs suivant l'axe 1 revient à prendre les données suivant l'axe 1 et effectuer les calculs dessus, donc ici en sortir une moyenne."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "array([[ 6.5, 11.5, 12.5],\n",
+ " [ 9. , 13. , 12. ]])"
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "marks.mean(axis=1) # give means for each exam in each subject"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "lang": "fr"
+ },
+ "source": [
+ "Un autre facon de voir les axes est de les considérer comme des __axes de projection__. Si je projette un objet 3D\n",
+ "suivant l'axe des $y$, le résultat est un objet 2D en $(x,z)$. On a ainsi une réduction de dimension.\n",
+ "\n",
+ "Si je somme sur l'axe 0 un tableau de dimension (2,4,3) comme l'est notre tableau de notes, cela veut dire que je perds la dimension 0 et donc la dimension du résultat est (4,3).\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(4, 3)"
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "marks.mean(axis=0).shape # mean along axis 0 (subjects) therefore this axis disapears"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "lang": "fr"
+ },
+ "source": [
+ "#### Quelques fonctions qui supportent les axes\n",
+ "\n",
+ "Toutes les fonctions qui s'appliquent à un ensemble de valeur pour produire un résultat\n",
+ "doivent pouvoir utiliser de concept d'axe (je ne les ai pas toutes\n",
+ "vérifiées mais n'hésitez pas à m'indiquer un contre-exemple). On a les fonctions mathématiques suivantes :\n",
+ "\n",
+ "* arithmétiques : `sum`, `prod`, `cumsum`, `cumprod` \n",
+ "* statistiques : `min`, `max`, `argmin`, `argmax`, `mean` (moyenne), `average` (moyenne pondérée), `std` (écart type), `var`, `median`, `percentile`, `quantile`\n",
+ "* autres : `gradiant`, `diff`, `fft`\n",
+ "\n",
+ "De plus il est possible de trier les valeurs d'un tableau suivant l'axe de son choix avec `sort`.\n",
+ "Par contre on ne peut les mélanger, avec [`shuffle`](https://docs.scipy.org/doc/numpy-1.15.1/reference/generated/numpy.random.shuffle.html#numpy.random.shuffle), que suivant l'axe 0.\n",
+ "\n",
+ "#### Appliquer une fonction suivant un axe\n",
+ "\n",
+ "La fonction [`apply_along_axis`](https://docs.scipy.org/doc/numpy-1.15.1/reference/generated/numpy.apply_along_axis.html)\n",
+ "permet d'appliquer une fonction 1D de son choix à un tableau suivant un axe. C'est l'axe qui va disparaître dans le résultat :"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "-> [ 7 13 11] 6\n",
+ "-> [ 7 7 13] 6\n",
+ "-> [ 5 9 11] 6\n",
+ "-> [ 7 17 15] 10\n",
+ "-> [ 8 12 14] 6\n",
+ "-> [ 8 12 12] 4\n",
+ "-> [ 8 12 10] 4\n",
+ "-> [12 16 12] 4\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "array([[ 6, 6, 6, 10],\n",
+ " [ 6, 4, 4, 4]])"
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "def diff_min_max(a):\n",
+ " print('->', a, a.max() - a.min())\n",
+ " return a.max() - a.min()\n",
+ "\n",
+ "np.apply_along_axis(diff_min_max, axis=-1, arr=marks) # -1 is the last axis, marks in our case"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "lang": "fr"
+ },
+ "source": [
+ "Question : c'est l'écart entre les notes de quoi ?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "lang": "fr"
+ },
+ "source": [
+ "#### Appliquer une fonction suivant plusieurs axes\n",
+ "\n",
+ "Certaines opérations peuvent prendre une liste d'axes et non un seul axe.\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "a.max \n",
+ " [17 16] \n",
+ "\n",
+ "a.max keepdim \n",
+ " [[[17]]\n",
+ "\n",
+ " [[16]]] \n",
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "print('a.max \\n', marks.max(axis=(1,2)), '\\n') \n",
+ "print('a.max keepdim \\n', marks.max(axis=(1,2), keepdims=True), '\\n') "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "lang": "fr"
+ },
+ "source": [
+ "Question : à quoi correspondent les 2 valeurs sorties ?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "lang": "fr"
+ },
+ "source": [
+ "Il est également peut utiliser la fonction [`apply_over_axes`](https://docs.scipy.org/doc/numpy-1.15.1/reference/generated/numpy.apply_over_axes.html#numpy.apply_over_axes) pour lui indiquer quelle\n",
+ "fonction doit être appliquée suivant les axes donnés.\n",
+ "\n",
+ "Attention la fonction donnée en argument recevra l'ensemble du tableau et l'axe sur lequel elle doit\n",
+ "travailler, les axes étant donnés les uns après les autres et le tableau étant modifié à chaque étape."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Apply over axis 1\n",
+ "[[[ 7 13 11]\n",
+ " [ 7 7 13]\n",
+ " [ 5 9 11]\n",
+ " [ 7 17 15]]\n",
+ "\n",
+ " [[ 8 12 14]\n",
+ " [ 8 12 12]\n",
+ " [ 8 12 10]\n",
+ " [12 16 12]]] \n",
+ "\n",
+ "Apply over axis 2\n",
+ "[[[ 7 17 15]]\n",
+ "\n",
+ " [[12 16 14]]] \n",
+ "\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "array([[[17]],\n",
+ "\n",
+ " [[16]]])"
+ ]
+ },
+ "execution_count": 6,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "def mymax(array, axis):\n",
+ " print('Apply over axis', axis)\n",
+ " print(array, '\\n')\n",
+ " return array.max(axis)\n",
+ "\n",
+ "np.apply_over_axes(mymax, marks, axes=(1,2))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "lang": "fr"
+ },
+ "source": [
+ "## Réorganisation d'un tableau\n",
+ "\n",
+ "On a déjà vu `reshape` pour changer la forme d'un tableau, `flatten` pour l'applatir en 1 dimension, regardons\n",
+ "d'autres fonctions de manipulation des tableaux.\n",
+ "\n",
+ "### Réordonner les axes\n",
+ "\n",
+ "#### `moveaxis` déplace un axe\n",
+ "\n",
+ "Dans notre exemple de notes, les 3 axes sont les matières, les étudiants et les examens.\n",
+ "La fonction `moveaxis` permet de déplacer un axe. Si ainsi je désire que les examens deviennent le premier axe\n",
+ "afin d'en faire ressortir les notes, je déplace l'axe 2 à la position 0 et les autres axes glissent pour faire de la place, l'axe 0 devient l'axe 1 et l'axe 1 devient l'axe 2 :"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "marks.shape = (2, 4, 3) \n",
+ "\n",
+ "b.shape = (3, 2, 4)\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "array([[[ 7, 7, 5, 7],\n",
+ " [ 8, 8, 8, 12]],\n",
+ "\n",
+ " [[13, 7, 9, 17],\n",
+ " [12, 12, 12, 16]],\n",
+ "\n",
+ " [[11, 13, 11, 15],\n",
+ " [14, 12, 10, 12]]])"
+ ]
+ },
+ "execution_count": 7,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "print('marks.shape = ',marks.shape, '\\n')\n",
+ "b = np.moveaxis(marks, 2, 0) \n",
+ "print('b.shape = ', b.shape)\n",
+ "b"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "lang": "fr"
+ },
+ "source": [
+ "Il est plus simple de voir ainsi que le premier examen a été difficile."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "lang": "fr"
+ },
+ "source": [
+ "#### `swapaxes` échange 2 axes\n",
+ "\n",
+ "Plutôt que d'insérer un axe à une nouvelle position et faire glisser les autres, on peut vouloir en échanger deux.\n",
+ "Voici comme avoir les notes pour chaque matière et chaque examen : "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "array([[[ 7, 7, 5, 7],\n",
+ " [13, 7, 9, 17],\n",
+ " [11, 13, 11, 15]],\n",
+ "\n",
+ " [[ 8, 8, 8, 12],\n",
+ " [12, 12, 12, 16],\n",
+ " [14, 12, 10, 12]]])"
+ ]
+ },
+ "execution_count": 8,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "marks.swapaxes(1,2)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "lang": "fr"
+ },
+ "source": [
+ "#### `transpose` pour tout faire\n",
+ "\n",
+ "Enfin `transpose` permet de réordonner tous les axes comme on veut, ainsi : `transpose((2,0,1))` met\n",
+ "\n",
+ "* l'axe 2 en place 0, \n",
+ "* l'axe 0 en place 1 \n",
+ "* l'axe 1 en place 2.\n",
+ "\n",
+ "#### Un apply over axis plus simple et plus rapide\n",
+ "\n",
+ "Malheureusement la fonction `apply_over_axis` n'est pas optimisée, aussi dans certaints il peut\n",
+ "être préférable de faire une boucle sur son tableau, ce qui veut dire mettre les axes qui vont rester au début et ceux sur lesquels on fait notre réduction à la fin :"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Means per students [10.833333333333334, 9.833333333333334, 9.166666666666666, 13.166666666666666]\n",
+ "24 µs ± 2.01 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)\n",
+ "29.6 µs ± 1.23 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(\"Means per students\", [m.mean() for m in marks.transpose((1,0,2))])\n",
+ "\n",
+ "%timeit [m.mean() for m in marks.transpose((1,0,2))]\n",
+ "%timeit np.apply_over_axes(np.mean, marks, axes=(0,2))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "lang": "fr"
+ },
+ "source": [
+ "### Changer l'ordre des éléments d'un tableau\n",
+ "\n",
+ "On peut inverser les valeurs d'un tableau suivant un axe avec [`flip`](https://docs.scipy.org/doc/numpy-1.15.1/reference/generated/numpy.flip.html#numpy.flip)\n",
+ "ce qui peut aussi être fait en l'indiquant au niveau des indices. Ainsi `np.flip(a, n)` est équivalent à \n",
+ "`a[:,:,..,::-1,:,..,:]` avec `::-1` en $n$-ième position.\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "array([[[12, 13, 14, 15],\n",
+ " [16, 17, 18, 19],\n",
+ " [20, 21, 22, 23]],\n",
+ "\n",
+ " [[ 0, 1, 2, 3],\n",
+ " [ 4, 5, 6, 7],\n",
+ " [ 8, 9, 10, 11]]])"
+ ]
+ },
+ "execution_count": 10,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "a = np.arange(24).reshape([2,3,4])\n",
+ "np.flip(a,0)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "lang": "fr"
+ },
+ "source": [
+ "On peut faire glisser les valeurs suivant un axe avec `roll` en spécifiant de combien on les fait glisser :"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "array([[[ 4, 5, 6, 7],\n",
+ " [ 8, 9, 10, 11],\n",
+ " [ 0, 1, 2, 3]],\n",
+ "\n",
+ " [[16, 17, 18, 19],\n",
+ " [20, 21, 22, 23],\n",
+ " [12, 13, 14, 15]]])"
+ ]
+ },
+ "execution_count": 11,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "np.roll(a, 2, axis=1) # roll elements by 2 along axis 1"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "lang": "fr"
+ },
+ "source": [
+ "La transposée s'applique aussi quelque soit la dimension. Par défaut elle inverse l'ordre des axes mais on peut \n",
+ "spécifier l'ordre voulu en sortie."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "array([[[ 0, 12],\n",
+ " [ 4, 16],\n",
+ " [ 8, 20]],\n",
+ "\n",
+ " [[ 1, 13],\n",
+ " [ 5, 17],\n",
+ " [ 9, 21]],\n",
+ "\n",
+ " [[ 2, 14],\n",
+ " [ 6, 18],\n",
+ " [10, 22]],\n",
+ "\n",
+ " [[ 3, 15],\n",
+ " [ 7, 19],\n",
+ " [11, 23]]])"
+ ]
+ },
+ "execution_count": 12,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "a.T"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "array([[[ 0, 4, 8],\n",
+ " [ 1, 5, 9],\n",
+ " [ 2, 6, 10],\n",
+ " [ 3, 7, 11]],\n",
+ "\n",
+ " [[12, 16, 20],\n",
+ " [13, 17, 21],\n",
+ " [14, 18, 22],\n",
+ " [15, 19, 23]]])"
+ ]
+ },
+ "execution_count": 13,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "np.transpose(a, (0,2,1))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "lang": "fr"
+ },
+ "source": [
+ "## Agrégation\n",
+ "\n",
+ "### Concaténation\n",
+ "\n",
+ "La fonction de base est [`concatenate`](https://docs.scipy.org/doc/numpy-1.15.0/reference/generated/numpy.concatenate.html) en indiquant l'axe choisi pour la concaténation. C'est à mon avis la méthode\n",
+ "la plus sûre et elle marche quelque soit la dimension.\n",
+ "\n",
+ "Cela étant on peut utiliser pour des tableaux 2D ou 3D :\n",
+ "\n",
+ "* `vstack` ou `row_stack` pour la concaténation vertical \n",
+ "* `hstack` ou `column_stack` pour la concaténation horizontal\n",
+ "* `dstack` pour la concaténation en profondeur (_deep_).\n",
+ "\n",
+ "Toutes ces fonctions prennent une liste de tableaux à concaténer comme argument. Bien sûr les tailles des tableaux doivent être compatibles."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[[0. 0. 0.]\n",
+ " [0. 0. 0.]\n",
+ " [1. 1. 1.]\n",
+ " [1. 1. 1.]] \n",
+ "\n",
+ "[[0. 0. 0. 1. 1. 1.]\n",
+ " [0. 0. 0. 1. 1. 1.]]\n"
+ ]
+ }
+ ],
+ "source": [
+ "a = np.zeros((2,3))\n",
+ "b = np.ones((2,3))\n",
+ "\n",
+ "print(np.concatenate((a,b), axis=0), '\\n') # same than vstack\n",
+ "print(np.hstack((a,b))) # same than concatenate with axis=1"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "lang": "fr"
+ },
+ "source": [
+ "### Empilage\n",
+ "\n",
+ "A la différence de la concaténation, l'empilage ajoute une dimension.\n",
+ "Empiler est utile pour stocker un paquet de tableaux 2D, des images par exemple, dans un tableau 3D. \n",
+ "On utilise la fonction [`stack`](https://docs.scipy.org/doc/numpy-1.15.1/reference/generated/numpy.stack.html)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "array([[[0., 0., 0.],\n",
+ " [0., 0., 0.]],\n",
+ "\n",
+ " [[1., 1., 1.],\n",
+ " [1., 1., 1.]]])"
+ ]
+ },
+ "execution_count": 15,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "c = np.stack((a,b)) # c[0] is a\n",
+ "c"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "lang": "fr"
+ },
+ "source": [
+ "Notez que `stack` a une option `axis` pour indiquer la direction dans laquelle on désire stocker les tableaux donnés."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "lang": "fr"
+ },
+ "source": [
+ "## Découpage\n",
+ "\n",
+ "La fonction inverse de la concaténation est le découpage avec [`split`](https://docs.scipy.org/doc/numpy-1.15.1/reference/generated/numpy.split.html#numpy.split) qui demande comme arguments :\n",
+ "\n",
+ "* le tableau à découper\n",
+ "* en combien de morceaux ou à quels indices\n",
+ "* la direction (l'axe)\n",
+ "\n",
+ "Pour retrouver nos deux tableaux qui ont généré le résultat de la cellule précédante on coupe en 2 suivant l'axe 0. On peut aussi couper suivant un autre axe."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "split part 1\n",
+ " [[[0. 0. 0.]]\n",
+ "\n",
+ " [[1. 1. 1.]]] \n",
+ "\n",
+ "split part 2\n",
+ " [[[0. 0. 0.]]\n",
+ "\n",
+ " [[1. 1. 1.]]]\n"
+ ]
+ }
+ ],
+ "source": [
+ "e,f = np.split(c, 2, 1) # splits in 2 along axis 1\n",
+ "print(\"split part 1\\n\", e, '\\n')\n",
+ "print(\"split part 2\\n\", f)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "lang": "fr"
+ },
+ "source": [
+ "Il existe aussi `hsplit`, `vsplit` et `dsplit` pour découper suivant les axes 0, 1 et 2.\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "lang": "fr"
+ },
+ "source": [
+ "## From Python to Numpy\n",
+ "\n",
+ "Si vous désirez creuser et regarder de nombreux exemples, vous pouvez lire le livre de N. Rougier [From Python to Numpy](https://www.labri.fr/perso/nrougier/from-python-to-numpy/)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "lang": "fr"
+ },
+ "source": [
+ "\n",
+ "## Pandas aussi\n",
+ "\n",
+ "On retrouvera ces manipulations avec Pandas qui est le super tableur de Python. Il travaille aussi sur des \n",
+ "structures en forme de tableau mais sans la contrainte que toutes les valeurs soient du même type.\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "variables": {
+ " PreviousNext(\"np02 Filtres.ipynb\", \"np04 Xarray.ipynb\")": "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br/><center><a href=\"np02 Filtres.ipynb\">np02 Filtres</a>&nbsp; ← <a href=\"http://python3.mooc.lrde.epita.fr/notebooks/Table%20des%20mati%C3%A8res.ipynb\" style=\"text-decoration:none\"> △ </a> → &nbsp;<a href=\"np04 Xarray.ipynb\">np04 Xarray</a></center><br/>&nbsp;"
+ }
+ },
+ "source": [
+ "{{ PreviousNext(\"np02 Filtres.ipynb\", \"np04 Xarray.ipynb\")}}"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ]
+} \ No newline at end of file