{ "metadata": { "name": "", "signature": "sha256:094970f3f7600aed9df619d84bc2f95367efd522cc3e4420116ffa9ce2e167c1" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Un poco de proselitismo" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Acerca de Pybonacci: \n", "\n", "![image](https://avatars3.githubusercontent.com/u/3338148?s=140)\n", "\n", "* [@pybonacci](https://twitter.com/Pybonacci)\n", "* [blog de pybonacci](http://pybonacci.wordpress.com)\n", "* [Github de pybonacci](https://github.com/Pybonacci)" ] }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Bueno, a lo que vamos, PANDAS..." ] }, { "cell_type": "code", "collapsed": false, "input": [ "import pandas as pd\n", "import sys\n", "import datetime as dt\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "import matplotlib\n", "\n", "%matplotlib inline\n", "\n", "print(\"Versi\u00f3n de Python: \", sys.version)\n", "print(\"Versi\u00f3n de Pandas: \", pd.version.short_version)\n", "print(\"Versi\u00f3n de Numpy: \", np.version.short_version)\n", "print(\"Versi\u00f3n de Matplotlib: \", matplotlib.__version__)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Versi\u00f3n de Python: 3.3.1 (default, Apr 10 2013, 19:05:32) \n", "[GCC 4.6.3]\n", "Versi\u00f3n de Pandas: 0.13.1\n", "Versi\u00f3n de Numpy: 1.8.1\n", "Versi\u00f3n de Matplotlib: 1.3.1\n" ] }, { "output_type": "stream", "stream": "stderr", "text": [ "/home/kiko/pyprojs/venvs/vepy331/lib/python3.3/importlib/_bootstrap.py:313: UserWarning: Module readline was already imported from /home/kiko/pyprojs/venvs/vepy331/lib/python3.3/lib-dynload/readline.cpython-33m.so, but /home/kiko/pyprojs/venvs/vepy331/lib/python3.3/site-packages is being added to sys.path\n", " return f(*args, **kwds)\n" ] } ], "prompt_number": 1 }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "\u00bfQu\u00e9 es Pandas?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pandas es una librer\u00eda que proporciona estructuras de datos flexibles y permite trabajar con la informaci\u00f3n de forma eficiente (gran parte de Pandas est\u00e1 implementado usando C/Cython para obtener un buen rendimiento).\n", "\n", "Funciona muy bien cuando nos toca trabajar con:\n", "\n", "* Datos heterog\u00e9neos que pueden distribuirse de forma tabular.\n", "* Series temporales\n", "* Matrices\n", "* ..." ] }, { "cell_type": "code", "collapsed": false, "input": [ "from IPython.core.display import HTML\n", "HTML(\"\")" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "" ], "metadata": {}, "output_type": "pyout", "prompt_number": 2, "text": [ "" ] } ], "prompt_number": 2 }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Estructuras de datos" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pandas ofrece varias estructuras de datos que nos resultar\u00e1n de mucha utilidad y que vamos a ir viendo poco a poco. Todas las posibles estructuras de datos que ofrece a d\u00eda de hoy son:\n", "\n", " * Series (y TimeSeries)\n", "\n", " * DataFrame\n", "\n", " * Panel\n", "\n", " * Panel4D\n", "\n", " * PanelND" ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Series" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "En una instancia de la clase `Series` podremos almacenar *arrays* o vectores con \u00edndice o etiqueta. Si no usamos \u00edndice o etiqueta nos lo numerar\u00e1 con un \u00edndice de forma interna. La forma b\u00e1sica de crear una `Series` ser\u00eda:\n", "\n", " >>> s = Series(data, index=index)\n", "\n", "donde data es el vector de datos e index (opcional) es el vector de \u00edndices que usar\u00e1 la serie. Si los \u00edndices son datos de fechas directamente se crear\u00e1 una instancia de una `TimeSeries` en lugar de una instacia de `Series`. \n", "\n", "Veamos un ejemplo de como crear este tipo de contenedor de datos. Primero vamos a crear una serie y **pandas** nos crear\u00e1 \u00edndices autom\u00e1ticamente, segundo vamos a crear una serie donde nosotros le vamos a decir los \u00edndices que queremos usar y, tercero, vamos a crear una serie temporal usando \u00edndices que son fechas." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# serie con \u00edndices autom\u00e1ticos\n", "serie = pd.Series(np.random.randn(10))\n", "print(u'Serie con \u00edndices autom\u00e1ticos \\n{} \\n'.format(serie))\n", "print(type(serie))" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Serie con \u00edndices autom\u00e1ticos \n", "0 -1.731792\n", "1 0.492089\n", "2 0.190005\n", "3 0.498570\n", "4 -0.129411\n", "5 0.496611\n", "6 -0.561550\n", "7 -0.981822\n", "8 -0.471803\n", "9 -0.255938\n", "dtype: float64 \n", "\n", "\n" ] } ], "prompt_number": 3 }, { "cell_type": "code", "collapsed": false, "input": [ "# serie con \u00edndices definidos por mi\n", "serie = pd.Series(np.random.randn(4), index = ['itzi','kikolas','dieguete','nicolasete'])\n", "print(u'Serie con \u00edndices definidos \\n{} \\n'.format(serie))\n", "print(type(serie))" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Serie con \u00edndices definidos \n", "itzi 0.130432\n", "kikolas -2.378303\n", "dieguete 0.951302\n", "nicolasete 1.846942\n", "dtype: float64 \n", "\n", "\n" ] } ], "prompt_number": 4 }, { "cell_type": "code", "collapsed": false, "input": [ "# serie(serie temporal) con \u00edndices que son fechas\n", "serie = pd.Series(np.random.randn(31), index = pd.date_range('2013/01/01', periods = 31))\n", "print(u'Serie temporal con \u00edndices de fechas \\n{} \\n'.format(serie))\n", "print(type(serie))" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Serie temporal con \u00edndices de fechas \n", "2013-01-01 0.086782\n", "2013-01-02 -0.274399\n", "2013-01-03 -0.919958\n", "2013-01-04 0.749879\n", "2013-01-05 -1.739752\n", "2013-01-06 0.861299\n", "2013-01-07 -0.797413\n", "2013-01-08 -0.650584\n", "2013-01-09 0.880755\n", "2013-01-10 -0.235406\n", "2013-01-11 0.134650\n", "2013-01-12 -0.255786\n", "2013-01-13 -0.068295\n", "2013-01-14 0.010727\n", "2013-01-15 0.259768\n", "2013-01-16 2.449214\n", "2013-01-17 -1.452189\n", "2013-01-18 -0.846709\n", "2013-01-19 -0.835064\n", "2013-01-20 -0.073190\n", "2013-01-21 0.853177\n", "2013-01-22 -0.239683\n", "2013-01-23 0.149482\n", "2013-01-24 -0.233044\n", "2013-01-25 0.073302\n", "2013-01-26 -1.769805\n", "2013-01-27 -1.016134\n", "2013-01-28 0.378350\n", "2013-01-29 0.190374\n", "2013-01-30 -1.566578\n", "2013-01-31 1.601782\n", "Freq: D, dtype: float64 \n", "\n", "\n" ] } ], "prompt_number": 5 }, { "cell_type": "markdown", "metadata": {}, "source": [ "En los ejemplos anteriores hemos creado las series a partir de un *numpy* *array* pero las podemos crear a partir de muchas otras cosas: listas, diccionarios, *numpy arrays*,... Veamos ejemplos:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "serie_lista = pd.Series([i*i for i in range(10)])\n", "print('Serie a partir de una lista \\n{} \\n'.format(serie_lista))\n", "\n", "dicc = {'cuadrado de {}'.format(i) : i*i for i in range(10)}\n", "serie_dicc = pd.Series(dicc)\n", "print('Serie a partir de un diccionario \\n{} \\n'.format(serie_dicc))\n", "\n", "serie_serie = pd.Series(serie_dicc.values)\n", "print('Serie a partir de los valores de otra (pandas)serie \\n{} \\n'.format(serie_serie))\n", "\n", "serie_cte = pd.Series(-999, index = np.arange(10))\n", "print('Serie a partir de un valor constante \\n{} \\n'.format(serie_cte))\n", "\n", "#..." ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Serie a partir de una lista \n", "0 0\n", "1 1\n", "2 4\n", "3 9\n", "4 16\n", "5 25\n", "6 36\n", "7 49\n", "8 64\n", "9 81\n", "dtype: int64 \n", "\n", "Serie a partir de un diccionario \n", "cuadrado de 0 0\n", "cuadrado de 1 1\n", "cuadrado de 2 4\n", "cuadrado de 3 9\n", "cuadrado de 4 16\n", "cuadrado de 5 25\n", "cuadrado de 6 36\n", "cuadrado de 7 49\n", "cuadrado de 8 64\n", "cuadrado de 9 81\n", "dtype: int64 \n", "\n", "Serie a partir de los valores de otra (pandas)serie \n", "0 0\n", "1 1\n", "2 4\n", "3 9\n", "4 16\n", "5 25\n", "6 36\n", "7 49\n", "8 64\n", "9 81\n", "dtype: int64 \n", "\n", "Serie a partir de un valor constante \n", "0 -999\n", "1 -999\n", "2 -999\n", "3 -999\n", "4 -999\n", "5 -999\n", "6 -999\n", "7 -999\n", "8 -999\n", "9 -999\n", "dtype: int64 \n", "\n" ] } ], "prompt_number": 6 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Una serie (`Series` o `TimeSeries`) se puede manejar igual que si tuvi\u00e9ramos un *numpy array* de una dimensi\u00f3n o igual que si tuvi\u00e9ramos un diccionario. Vemos ejemplos de esto:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "serie = pd.Series(np.random.randn(10), index = ['a','b','c','d','e','f','g','h','i','j'])\n", "print('Serie que vamos a usar en este ejemplo: \\n{}\\n\\n'.format(serie))\n", "\n", "# Ejemplos de comportamiento como numpy array\n", "print('Se comporta como un numpy array:')\n", "print('================================')\n", "print('>>> serie.max()\\n{}'.format(serie.max()))\n", "print('>>> serie.sum()\\n{}'.format(serie.sum()))\n", "print('>>> serie.abs()\\n{}'.format(serie.abs()))\n", "print('>>> serie[serie > 0]\\n{}'.format(serie[serie > 0]))\n", "#...\n", "\n", "print('\\n')\n", "\n", "# Ejemplos de comportamiento como diccionario\n", "print(\"Se comporta como un diccionario:\")\n", "print(\"================================\")\n", "print(\">>> serie['a']\\n{}\".format(serie['a']))\n", "print(\">>> 'a' in serie\\n{}\".format('a' in serie))\n", "print(\">>> 'z' in serie\\n{}\".format('z' in serie))" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Serie que vamos a usar en este ejemplo: \n", "a -0.663462\n", "b 0.893211\n", "c -0.312062\n", "d -1.196054\n", "e 1.608529\n", "f -0.045494\n", "g -0.192866\n", "h 1.681370\n", "i -0.503151\n", "j -0.078362\n", "dtype: float64\n", "\n", "\n", "Se comporta como un numpy array:\n", "================================\n", ">>> serie.max()\n", "1.6813703206498873\n", ">>> serie.sum()\n", "1.1916586064903802\n", ">>> serie.abs()\n", "a 0.663462\n", "b 0.893211\n", "c 0.312062\n", "d 1.196054\n", "e 1.608529\n", "f 0.045494\n", "g 0.192866\n", "h 1.681370\n", "i 0.503151\n", "j 0.078362\n", "dtype: float64" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n", ">>> serie[serie > 0]\n", "b 0.893211\n", "e 1.608529\n", "h 1.681370\n", "dtype: float64\n", "\n", "\n", "Se comporta como un diccionario:\n", "================================\n", ">>> serie['a']\n", "-0.663462354872233\n", ">>> 'a' in serie\n", "True\n", ">>> 'z' in serie\n", "False\n" ] } ], "prompt_number": 7 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Las operaciones est\u00e1n 'vectorizadas' y se hacen elemento a elemento con los elementos alineados en funci\u00f3n del \u00edndice. Si se hace, por ejemplo, una suma de dos series, si en una de las dos series no existe un elemento, i.e. el \u00edndice no existe en la serie, el resultado para ese \u00edndice ser\u00e1 `nan`. En resumen, estamos haciendo una __uni\u00f3n__ de los \u00edndices y funciona diferente a los `numpy` arrays. Se puede ver el esquema en el siguiente ejemplo:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "s1 = serie[1:]\n", "s2 = serie[:-1]\n", "suma = s1 + s2\n", "print(' s1 s2 s1 + s2')\n", "print('------------------ ------------------ ------------------')\n", "for clave in sorted(set(list(s1.keys()) + list(s2.keys()))):\n", " print('{0:1} {1:20} + {0:1} {2:20} = {0:1} {3:20}'.format(clave, \n", " s1.get(clave), \n", " s2.get(clave), \n", " suma.get(clave)))\n", "# En la anterior l\u00ednea de c\u00f3digo uso el m\u00e9todo get para no obtener un KeyError \n", "# como s\u00ed obtendr\u00eda si uso, p.e., s1['a']" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ " s1 s2 s1 + s2\n", "------------------ ------------------ ------------------\n", "a None + a -0.663462354872233 = a nan\n", "b 0.8932105297090326 + b 0.8932105297090326 = b 1.7864210594180652\n", "c -0.31206215624310224 + c -0.31206215624310224 = c -0.6241243124862045\n", "d -1.1960537478238258 + d -1.1960537478238258 = d -2.3921074956476516\n", "e 1.6085289802454341 + e 1.6085289802454341 = e 3.2170579604908682\n", "f -0.0454943963901047 + f -0.0454943963901047 = f -0.0909887927802094\n", "g -0.19286571253906507 + g -0.19286571253906507 = g -0.38573142507813013\n", "h 1.6813703206498873 + h 1.6813703206498873 = h 3.3627406412997747\n", "i -0.503150771440017 + i -0.503150771440017 = i -1.006301542880034\n", "j -0.07836208480562608 + j None = j nan\n" ] } ], "prompt_number": 8 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "DataFrame" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Un DataFrame se puede ver como si fuera una tabla con \u00edndices para las filas y las columnas. Es algo similar a lo que tenemos en una hoja de c\u00e1lculo, una tabla de una BBDD __SQL__ o un diccionario de `series` Pandas. Esta ser\u00e1 la estructura de datos m\u00e1s habitual a usar. El `DataFrame` se puede crear a partir de muchas otras estructuras de datos:\n", "\n", " * A partir de un diccionario de `numpy` arrays de 1D, diccionarios de listas, diccionarios de diccionarios o diccionarios de Series.\n", " * A partir de un `numpy` array de 2D\n", " * A partir de un `numpy` array estructurado ([*structured ndarray* o *record ndarray*](http://docs.scipy.org/doc/numpy/user/basics.rec.html))\n", " * A partir de una `Series` de Pandas\n", " * A partir de otro `DataFrame`de Pandas\n", "\n", "Adem\u00e1s de los datos, podemos definir los \u00edndices (las etiquetas para las filas) o las columnas (etiquetas para las mismas). Si no se define nada al crear el `DataFrame` se usar\u00e1n normas del sentido com\u00fan para nombrar los \u00edndices de filas y columnas.\n", "\n", "Veamos un poco de c\u00f3digo para ver esto:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "df_lista = pd.DataFrame({'a': [11,12,13], 'b': [21,22,23]})\n", "print('DataFrame a partir de un diccionario de listas \\n{} \\n'.format(df_lista))\n", "\n", "df_np1D = pd.DataFrame({'a': np.arange(3)**2, 'b': np.random.randn(3)})\n", "print('DataFrame a partir de un diccionario de 1D ndarrays \\n{} \\n'.format(df_np1D))\n", "\n", "df_np2D = pd.DataFrame(np.empty((5,3)), \n", " index = ['primero','segundo','tercero','cuarto','quinto'], \n", " columns = ['velocidad', 'temperatura','presion'])\n", "print('DataFrame a partir de un 2D ndarray \\n{} \\n'.format(df_np2D))\n", "\n", "df_df = pd.DataFrame(df_np2D, index = ['primero','segundo','tercero'])\n", "df_df.index = ['first','second','third']\n", "print('DataFrame a partir de los valores de otro (pandas)DataFrame \\n{} \\n'.format(df_df))\n", "\n", "#..." ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "DataFrame a partir de un diccionario de listas \n", " a b\n", "0 11 21\n", "1 12 22\n", "2 13 23\n", "\n", "[3 rows x 2 columns] \n", "\n", "DataFrame a partir de un diccionario de 1D ndarrays \n", " a b\n", "0 0 -0.818739\n", "1 1 -1.473575\n", "2 4 -0.014659\n", "\n", "[3 rows x 2 columns] \n", "\n", "DataFrame a partir de un 2D ndarray \n", " velocidad temperatura presion\n", "primero 1.397157e-306 4.311076e-314 0.000000e+00\n", "segundo 1.670358e-179 -1.238962e-65 -2.110672e-44\n", "tercero -3.645480e-42 0.000000e+00 -1.561315e-65\n", "cuarto -2.623582e-42 0.000000e+00 1.519743e-314\n", "quinto -2.578083e-42 0.000000e+00 2.413050e-312\n", "\n", "[5 rows x 3 columns] \n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n", "DataFrame a partir de los valores de otro (pandas)DataFrame \n", " velocidad temperatura presion\n", "first 1.397157e-306 4.311076e-314 0.000000e+00\n", "second 1.670358e-179 -1.238962e-65 -2.110672e-44\n", "third -3.645480e-42 0.000000e+00 -1.561315e-65\n", "\n", "[3 rows x 3 columns] \n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n" ] } ], "prompt_number": 9 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Podemos construir un `DataFrame` a partir de [constructores alternativos](http://pandas.pydata.org/pandas-docs/stable/dsintro.html#alternate-constructors) como `pd.DataFrame.from_dict`, `pd.DataFrame.from_records` o `pd.DataFrame.from_items`." ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Panel, Panel4D, PanelND" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "En general, los paneles son para tipos de datos de m\u00e1s de dos dimensiones. No los vamos a cubrir ya que se consideran un pel\u00edn m\u00e1s complejos, de uso menos habitual y/o se encuentran en estado experimental con lo que pueden cambiar bastante en el corto/medio plazo. Se puede consultar la documentaci\u00f3n oficial pulsando sobre:\n", "\n", " * [Panel](http://pandas.pydata.org/pandas-docs/stable/dsintro.html#panel)\n", " * [Panel4D](http://pandas.pydata.org/pandas-docs/stable/dsintro.html#panel4d-experimental)\n", " * [PanelND](http://pandas.pydata.org/pandas-docs/stable/dsintro.html#panelnd-experimental)" ] }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Leyendo y escribiendo datos (IO)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Una de las cosas que m\u00e1s me gusta de Pandas es la potencia que aporta a lo hora de leer y/o escribir ficheros de datos. Pandas es capaz de leer datos de ficheros csv, excel, HDF5, sql, json, html,...\n", "\n", "Si trabaj\u00e1is con datos de terceros, que pueden provenir de muy diversas fuentes, una de las partes m\u00e1s tediosas del trabajo ser\u00e1 tener los datos listos para empezar a trabajar. Limpiar huecos, poner fechas en formato usable, saltarse cabeceros,...\n", "\n", "Sin duda, una de las [funciones que usar\u00e9is m\u00e1s ser\u00e1](http://pandas.pydata.org/pandas-docs/stable/io.html#csv-text-files) `read_csv()` que permite una gran flexibilidad a la hora de leer un fichero de texto plano.\n", "\n", "Veamos la documentaci\u00f3n:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " Docstring:\n", " Read CSV (comma-separated) file into DataFrame\n", "\n", " Also supports optionally iterating or breaking of the file\n", " into chunks.\n", "\n", " Parameters\n", " ----------\n", " filepath_or_buffer : string or file handle / StringIO. The string could be\n", " a URL. Valid URL schemes include http, ftp, s3, and file. For file URLs, a\n", " host is expected. For instance, a local file could be\n", " file ://localhost/path/to/table.csv\n", " sep : string, default ','\n", " Delimiter to use. If sep is None, will try to automatically determine\n", " this. Regular expressions are accepted.\n", "\n", " lineterminator : string (length 1), default None\n", " Character to break file into lines. Only valid with C parser\n", " quotechar : string (length 1)\n", " The character used to denote the start and end of a quoted item. Quoted\n", " items can include the delimiter and it will be ignored.\n", " quoting : int or csv.QUOTE_* instance, default None\n", " Control field quoting behavior per ``csv.QUOTE_*`` constants. Use one of\n", " QUOTE_MINIMAL (0), QUOTE_ALL (1), QUOTE_NONNUMERIC (2) or QUOTE_NONE (3).\n", " Default (None) results in QUOTE_MINIMAL behavior.\n", " skipinitialspace : boolean, default False\n", " Skip spaces after delimiter\n", " escapechar : string\n", " dtype : Type name or dict of column -> type\n", " Data type for data or columns. E.g. {'a': np.float64, 'b': np.int32}\n", " compression : {'gzip', 'bz2', None}, default None\n", " For on-the-fly decompression of on-disk data\n", " dialect : string or csv.Dialect instance, default None\n", " If None defaults to Excel dialect. Ignored if sep longer than 1 char\n", " See csv.Dialect documentation for more details\n", " header : int row number(s) to use as the column names, and the start of the\n", " data. Defaults to 0 if no ``names`` passed, otherwise ``None``. Explicitly\n", " pass ``header=0`` to be able to replace existing names. The header can be\n", " a list of integers that specify row locations for a multi-index on the\n", " columns E.g. [0,1,3]. Intervening rows that are not specified will be\n", " skipped. (E.g. 2 in this example are skipped)\n", " skiprows : list-like or integer\n", " Row numbers to skip (0-indexed) or number of rows to skip (int)\n", " at the start of the file\n", " index_col : int or sequence or False, default None\n", " Column to use as the row labels of the DataFrame. If a sequence is given, a\n", " MultiIndex is used. If you have a malformed file with delimiters at the end\n", " of each line, you might consider index_col=False to force pandas to _not_\n", " use the first column as the index (row names)\n", " names : array-like\n", " List of column names to use. If file contains no header row, then you\n", " should explicitly pass header=None\n", " prefix : string or None (default)\n", " Prefix to add to column numbers when no header, e.g 'X' for X0, X1, ...\n", " na_values : list-like or dict, default None\n", " Additional strings to recognize as NA/NaN. If dict passed, specific\n", " per-column NA values\n", " true_values : list\n", " Values to consider as True\n", " false_values : list\n", " Values to consider as False\n", " keep_default_na : bool, default True\n", " If na_values are specified and keep_default_na is False the default NaN\n", " values are overridden, otherwise they're appended to\n", " parse_dates : boolean, list of ints or names, list of lists, or dict\n", " If True -> try parsing the index.\n", " If [1, 2, 3] -> try parsing columns 1, 2, 3 each as a separate date column.\n", " If [[1, 3]] -> combine columns 1 and 3 and parse as a single date column.\n", " {'foo' : [1, 3]} -> parse columns 1, 3 as date and call result 'foo'\n", " A fast-path exists for iso8601-formatted dates.\n", " keep_date_col : boolean, default False\n", " If True and parse_dates specifies combining multiple columns then\n", " keep the original columns.\n", " date_parser : function\n", " Function to use for converting a sequence of string columns to an\n", " array of datetime instances. The default uses dateutil.parser.parser\n", " to do the conversion.\n", " dayfirst : boolean, default False\n", " DD/MM format dates, international and European format\n", " thousands : str, default None\n", " Thousands separator\n", " comment : str, default None\n", " Indicates remainder of line should not be parsed\n", " Does not support line commenting (will return empty line)\n", " decimal : str, default '.'\n", " Character to recognize as decimal point. E.g. use ',' for European data\n", " nrows : int, default None\n", " Number of rows of file to read. Useful for reading pieces of large files\n", " iterator : boolean, default False\n", " Return TextFileReader object\n", " chunksize : int, default None\n", " Return TextFileReader object for iteration\n", " skipfooter : int, default 0\n", " Number of line at bottom of file to skip\n", " converters : dict. optional\n", " Dict of functions for converting values in certain columns. Keys can either\n", " be integers or column labels\n", " verbose : boolean, default False\n", " Indicate number of NA values placed in non-numeric columns\n", " delimiter : string, default None\n", " Alternative argument name for sep. Regular expressions are accepted.\n", " encoding : string, default None\n", " Encoding to use for UTF when reading/writing (ex. 'utf-8')\n", " squeeze : boolean, default False\n", " If the parsed data only contains one column then return a Series\n", " na_filter: boolean, default True\n", " Detect missing value markers (empty strings and the value of na_values). In\n", " data without any NAs, passing na_filter=False can improve the performance\n", " of reading a large file\n", " usecols : array-like\n", " Return a subset of the columns.\n", " Results in much faster parsing time and lower memory usage.\n", " mangle_dupe_cols: boolean, default True\n", " Duplicate columns will be specified as 'X.0'...'X.N', rather than 'X'...'X'\n", " tupleize_cols: boolean, default False\n", " Leave a list of tuples on columns as is (default is to convert to\n", " a Multi Index on the columns)\n", " error_bad_lines: boolean, default True\n", " Lines with too many fields (e.g. a csv line with too many commas) will by\n", " default cause an exception to be raised, and no DataFrame will be returned.\n", " If False, then these \"bad lines\" will dropped from the DataFrame that is\n", " returned. (Only valid with C parser).\n", " warn_bad_lines: boolean, default True\n", " If error_bad_lines is False, and warn_bad_lines is True, a warning for each\n", " \"bad line\" will be output. (Only valid with C parser).\n", " infer_datetime_format : boolean, default False\n", " If True and parse_dates is enabled for a column, attempt to infer\n", " the datetime format to speed up the processing\n", "\n", " Returns\n", " -------\n", " result : DataFrame or TextParser" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Vamos a inventarnos un fichero de datos..." ] }, { "cell_type": "code", "collapsed": false, "input": [ "%%writefile dummy.data\n", "cabecero est\u00fapido\n", "901001 0000 7.54 -11.67 1.07 4.27\n", "901001 0600 19.61 -2.74 27.87 -8.96\n", "901001 1200 -4.34 0.73 -6.58 0.17\n", "901001 1800 -4.99 3.24 10.62 -6.13\n", "901002 0000 -3.54 10.39 -12.05 -13.35\n", "901002 0600 12.55 3.80 4.92 -8.18\n", "901002 1200 1.06 23.75 -8.03 -8.67\n", "901002 1800 -1.12 1.82 7.09 -6.06\n", "901003 0600 -5.90 2.38 19.33 6.84\n", "901003 1200 -9.51 -2.72 -7.13 -0.35\n", "901003 1800 6.49 -12.01 -13.62 -0.93" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Overwriting dummy.data\n" ] } ], "prompt_number": 10 }, { "cell_type": "code", "collapsed": false, "input": [ "data = pd.read_csv('dummy.data', sep = '\\s*', \n", " names = ['fecha', 'hora', 'rec1', 'rec2', 'rec3', 'rec4'],\n", " skiprows = 1, parse_dates = [[0, 1]], index_col = 0)" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 11 }, { "cell_type": "code", "collapsed": false, "input": [ "print(data)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ " rec1 rec2 rec3 rec4\n", "fecha_hora \n", "1990-10-01 00:00:00 7.54 -11.67 1.07 4.27\n", "1990-10-01 06:00:00 19.61 -2.74 27.87 -8.96\n", "1990-10-01 12:00:00 -4.34 0.73 -6.58 0.17\n", "1990-10-01 18:00:00 -4.99 3.24 10.62 -6.13\n", "1990-10-02 00:00:00 -3.54 10.39 -12.05 -13.35\n", "1990-10-02 06:00:00 12.55 3.80 4.92 -8.18\n", "1990-10-02 12:00:00 1.06 23.75 -8.03 -8.67\n", "1990-10-02 18:00:00 -1.12 1.82 7.09 -6.06\n", "1990-10-03 06:00:00 -5.90 2.38 19.33 6.84\n", "1990-10-03 12:00:00 -9.51 -2.72 -7.13 -0.35\n", "1990-10-03 18:00:00 6.49 -12.01 -13.62 -0.93\n", "\n", "[11 rows x 4 columns]\n" ] } ], "prompt_number": 12 }, { "cell_type": "code", "collapsed": false, "input": [ "data.index" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 13, "text": [ "\n", "[1990-10-01 00:00:00, ..., 1990-10-03 18:00:00]\n", "Length: 11, Freq: None, Timezone: None" ] } ], "prompt_number": 13 }, { "cell_type": "code", "collapsed": false, "input": [ "data.columns" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 14, "text": [ "Index(['rec1', 'rec2', 'rec3', 'rec4'], dtype='object')" ] } ], "prompt_number": 14 }, { "cell_type": "markdown", "metadata": {}, "source": [ "**[Inciso]** Si no usamos `print`, el output del `DataFrame` se ver\u00e1 como una tabla HTML gracias a la magia de IPython notebook y de Pandas. En general, intentaremos usar `print` como en las anteriores piezas de c\u00f3digo y de aqu\u00ed en adelante para que se vea igual que si se usa algo distinto al notebook. En la pieza de c\u00f3digo siguiente no uso `print` para qu\u00e9 se vea de lo que hablo ;-)" ] }, { "cell_type": "code", "collapsed": false, "input": [ "#data[data.index >= dt.datetime(1990, 10, 2)]\n", "data[data.index >= \"1990-10-02\"]" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
rec1rec2rec3rec4
fecha_hora
1990-10-02 00:00:00 -3.54 10.39-12.05-13.35
1990-10-02 06:00:00 12.55 3.80 4.92 -8.18
1990-10-02 12:00:00 1.06 23.75 -8.03 -8.67
1990-10-02 18:00:00 -1.12 1.82 7.09 -6.06
1990-10-03 06:00:00 -5.90 2.38 19.33 6.84
1990-10-03 12:00:00 -9.51 -2.72 -7.13 -0.35
1990-10-03 18:00:00 6.49-12.01-13.62 -0.93
\n", "

7 rows \u00d7 4 columns

\n", "
" ], "metadata": {}, "output_type": "pyout", "prompt_number": 15, "text": [ " rec1 rec2 rec3 rec4\n", "fecha_hora \n", "1990-10-02 00:00:00 -3.54 10.39 -12.05 -13.35\n", "1990-10-02 06:00:00 12.55 3.80 4.92 -8.18\n", "1990-10-02 12:00:00 1.06 23.75 -8.03 -8.67\n", "1990-10-02 18:00:00 -1.12 1.82 7.09 -6.06\n", "1990-10-03 06:00:00 -5.90 2.38 19.33 6.84\n", "1990-10-03 12:00:00 -9.51 -2.72 -7.13 -0.35\n", "1990-10-03 18:00:00 6.49 -12.01 -13.62 -0.93\n", "\n", "[7 rows x 4 columns]" ] } ], "prompt_number": 15 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Escribir el resultado final en un fichero csv, por ejemplo, es algo tan sencillo como:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "data.to_csv('dummy.csv')" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 16 }, { "cell_type": "code", "collapsed": false, "input": [ "%load dummy.csv" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "fecha_hora,rec1,rec2,rec3,rec4\n", "1990-10-01 00:00:00,7.54,-11.67,1.07,4.27\n", "1990-10-01 06:00:00,19.61,-2.74,27.87,-8.96\n", "1990-10-01 12:00:00,-4.34,0.73,-6.58,0.17\n", "1990-10-01 18:00:00,-4.99,3.24,10.62,-6.13\n", "1990-10-02 00:00:00,-3.54,10.39,-12.05,-13.35\n", "1990-10-02 06:00:00,12.55,3.8,4.92,-8.18\n", "1990-10-02 12:00:00,1.06,23.75,-8.03,-8.67\n", "1990-10-02 18:00:00,-1.12,1.82,7.09,-6.06\n", "1990-10-03 06:00:00,-5.9,2.38,19.33,6.84\n", "1990-10-03 12:00:00,-9.51,-2.72,-7.13,-0.35\n", "1990-10-03 18:00:00,6.49,-12.01,-13.62,-0.93\n" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Otra tarea que se realiza habitualmente ser\u00eda la de trabajar con informaci\u00f3n de una base de datos SQL. No lo vamos a ver aqu\u00ed pero pod\u00e9is ver [este notebook donde se explica como leer y/o escribir datos de una BBDD SQL](http://nbviewer.ipython.org/github/jvns/pandas-cookbook/blob/master/cookbook/Chapter%209%20-%20Loading%20data%20from%20SQL%20databases.ipynb) (SQLite, PostgreSQL o MySQL). Una vez que se han le\u00eddo, el tratamiento es el mismo que si los hubi\u00e9semos le\u00eddo de otro origen." ] }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Trabajando con datos, indexaci\u00f3n, selecci\u00f3n,..." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\u00bfC\u00f3mo podemos seleccionar, a\u00f1adir, eliminar, mover,..., columnas, filas,...? \n", "\n", "Para seleccionar una columna solo hemos de usar el nombre de la columna y pasarlo como si fuera un diccionario (o un atributo). \n", "\n", "Para a\u00f1adir una columna simplemente hemos de usar un nombre de columna no existente y pasarle los valores para esa columna. \n", "\n", "Para eliminar una columna podemos usar `del` o el m\u00e9todo `pop`. \n", "\n", "Para mover una columna podemos usar una combinaci\u00f3n de las metodolog\u00edas anteriores." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Por ejemplo, vemos a seleccionar los valores de una columna:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "df = pd.DataFrame(np.random.randn(5,3), \n", " index = ['primero','segundo','tercero','cuarto','quinto'], \n", " columns = ['velocidad', 'temperatura','presion'])\n", "df['velocidad']" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 17, "text": [ "primero 0.175374\n", "segundo -0.133466\n", "tercero -0.418224\n", "cuarto -0.320517\n", "quinto 0.955521\n", "Name: velocidad, dtype: float64" ] } ], "prompt_number": 17 }, { "cell_type": "code", "collapsed": false, "input": [ "# Forma alternativa\n", "df.velocidad" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 18, "text": [ "primero 0.175374\n", "segundo -0.133466\n", "tercero -0.418224\n", "cuarto -0.320517\n", "quinto 0.955521\n", "Name: velocidad, dtype: float64" ] } ], "prompt_number": 18 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Vamos a a\u00f1adir una columna nueva al `DataFrame`:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "df['velocidad_maxima'] = np.random.randn(df.shape[0])\n", "print(df)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ " velocidad temperatura presion velocidad_maxima\n", "primero 0.175374 0.384571 -0.575126 -0.474630\n", "segundo -0.133466 0.987833 0.305844 -0.746577\n", "tercero -0.418224 0.603431 0.128822 1.545612\n", "cuarto -0.320517 -0.643183 0.319838 0.634203\n", "quinto 0.955521 -0.295541 -1.277743 2.389485\n", "\n", "[5 rows x 4 columns]\n" ] } ], "prompt_number": 19 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pero qu\u00e9 pasa si quiero a\u00f1adir la columna en un lugar espec\u00edfico. Para ello podemos usar el m\u00e9todo `insert` (y de paso vemos como podemos borrar una columna):" ] }, { "cell_type": "code", "collapsed": false, "input": [ "# forma 1 (borramos la columna 'velocidad_maxima' que est\u00e1 al final del df usando del)\n", "# (Colocamos la columna eliminada en la posici\u00f3n que especifiquemos)\n", "print(df)\n", "columna = df['velocidad_maxima']\n", "del df['velocidad_maxima']\n", "print(df)\n", "print(columna)\n", "df.insert(1, 'velocidad_maxima', columna)\n", "print(df)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ " velocidad temperatura presion velocidad_maxima\n", "primero 0.175374 0.384571 -0.575126 -0.474630\n", "segundo -0.133466 0.987833 0.305844 -0.746577\n", "tercero -0.418224 0.603431 0.128822 1.545612\n", "cuarto -0.320517 -0.643183 0.319838 0.634203\n", "quinto 0.955521 -0.295541 -1.277743 2.389485\n", "\n", "[5 rows x 4 columns]\n", " velocidad temperatura presion\n", "primero 0.175374 0.384571 -0.575126\n", "segundo -0.133466 0.987833 0.305844\n", "tercero -0.418224 0.603431 0.128822\n", "cuarto -0.320517 -0.643183 0.319838\n", "quinto 0.955521 -0.295541 -1.277743\n", "\n", "[5 rows x 3 columns]\n", "primero -0.474630\n", "segundo -0.746577\n", "tercero 1.545612\n", "cuarto 0.634203\n", "quinto 2.389485\n", "Name: velocidad_maxima, dtype: float64\n", " velocidad velocidad_maxima temperatura presion\n", "primero 0.175374 -0.474630 0.384571 -0.575126\n", "segundo -0.133466 -0.746577 0.987833 0.305844\n", "tercero -0.418224 1.545612 0.603431 0.128822\n", "cuarto -0.320517 0.634203 -0.643183 0.319838\n", "quinto 0.955521 2.389485 -0.295541 -1.277743\n", "\n", "[5 rows x 4 columns]" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n" ] } ], "prompt_number": 20 }, { "cell_type": "code", "collapsed": false, "input": [ "# forma 2 (borramos usando el m\u00e9todo pop y a\u00f1adimos la columna borrada en la \u00faltima posici\u00f3n de nuevo)\n", "print(df)\n", "columna = df.pop('velocidad_maxima')\n", "print(df)\n", "print(columna)\n", "df.insert(3, 'velocidad_maxima', columna)\n", "print(df)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ " velocidad velocidad_maxima temperatura presion\n", "primero 0.175374 -0.474630 0.384571 -0.575126\n", "segundo -0.133466 -0.746577 0.987833 0.305844\n", "tercero -0.418224 1.545612 0.603431 0.128822\n", "cuarto -0.320517 0.634203 -0.643183 0.319838\n", "quinto 0.955521 2.389485 -0.295541 -1.277743\n", "\n", "[5 rows x 4 columns]\n", " velocidad temperatura presion\n", "primero 0.175374 0.384571 -0.575126\n", "segundo -0.133466 0.987833 0.305844\n", "tercero -0.418224 0.603431 0.128822\n", "cuarto -0.320517 -0.643183 0.319838\n", "quinto 0.955521 -0.295541 -1.277743\n", "\n", "[5 rows x 3 columns]\n", "primero -0.474630\n", "segundo -0.746577\n", "tercero 1.545612\n", "cuarto 0.634203\n", "quinto 2.389485\n", "Name: velocidad_maxima, dtype: float64\n", " velocidad temperatura presion velocidad_maxima\n", "primero 0.175374 0.384571 -0.575126 -0.474630\n", "segundo -0.133466 0.987833 0.305844 -0.746577\n", "tercero -0.418224 0.603431 0.128822 1.545612\n", "cuarto -0.320517 -0.643183 0.319838 0.634203\n", "quinto 0.955521 -0.295541 -1.277743 2.389485\n", "\n", "[5 rows x 4 columns]" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n" ] } ], "prompt_number": 21 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Para seleccionar datos concretos de un `DataFrame` podemos usar el \u00edndice, una rebanada, valores booleanos, la columna,..." ] }, { "cell_type": "code", "collapsed": false, "input": [ "print('Seleccionamos la columna de velocidades')\n", "print(df['velocidad'])" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Seleccionamos la columna de velocidades\n", "primero 0.175374\n", "segundo -0.133466\n", "tercero -0.418224\n", "cuarto -0.320517\n", "quinto 0.955521\n", "Name: velocidad, dtype: float64\n" ] } ], "prompt_number": 22 }, { "cell_type": "code", "collapsed": false, "input": [ "print(u'Seleccionamos todas las columnas cuyo \u00edndice es igual a tercero')\n", "print(df.xs('tercero'))" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Seleccionamos todas las columnas cuyo \u00edndice es igual a tercero\n", "velocidad -0.418224\n", "temperatura 0.603431\n", "presion 0.128822\n", "velocidad_maxima 1.545612\n", "Name: tercero, dtype: float64\n" ] } ], "prompt_number": 23 }, { "cell_type": "code", "collapsed": false, "input": [ "print(u'Seleccionamos todas las columnas cuyo \u00edndice est\u00e1 entre tercero y quinto')\n", "print(u'Daos cuenta que en este caso los \u00edndices son inclusivos')\n", "print(df.ix['tercero':'quinto'])" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Seleccionamos todas las columnas cuyo \u00edndice est\u00e1 entre tercero y quinto\n", "Daos cuenta que en este caso los \u00edndices son inclusivos\n", " velocidad temperatura presion velocidad_maxima\n", "tercero -0.418224 0.603431 0.128822 1.545612\n", "cuarto -0.320517 -0.643183 0.319838 0.634203\n", "quinto 0.955521 -0.295541 -1.277743 2.389485\n", "\n", "[3 rows x 4 columns]\n" ] } ], "prompt_number": 24 }, { "cell_type": "code", "collapsed": false, "input": [ "print(u'Seleccionamos todos los valores de velocidad donde la temperatura > 0')\n", "print(df[df['temperatura'] > 0]['velocidad'])" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Seleccionamos todos los valores de velocidad donde la temperatura > 0\n", "primero 0.175374\n", "segundo -0.133466\n", "tercero -0.418224\n", "Name: velocidad, dtype: float64\n" ] } ], "prompt_number": 25 }, { "cell_type": "code", "collapsed": false, "input": [ "print('Seleccionamos todos los valores de una columna por \u00edndice usando una')\n", "print('rebanada (slice) de enteros')\n", "print('Daos cuenta que en este caso el l\u00edmite superior de la rebanada no se')\n", "print('incluye (Python tradicional)')\n", "print(df.ix[1:3])" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Seleccionamos todos los valores de una columna por \u00edndice usando una\n", "rebanada (slice) de enteros\n", "Daos cuenta que en este caso el l\u00edmite superior de la rebanada no se\n", "incluye (Python tradicional)\n", " velocidad temperatura presion velocidad_maxima\n", "segundo -0.133466 0.987833 0.305844 -0.746577\n", "tercero -0.418224 0.603431 0.128822 1.545612\n", "\n", "[2 rows x 4 columns]\n" ] } ], "prompt_number": 26 }, { "cell_type": "code", "collapsed": false, "input": [ "print(u'Seleccionamos filas y columnas')\n", "print(df.ix[1:3, ['velocidad', 'presion']])" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Seleccionamos filas y columnas\n", " velocidad presion\n", "segundo -0.133466 0.305844\n", "tercero -0.418224 0.128822\n", "\n", "[2 rows x 2 columns]\n" ] } ], "prompt_number": 28 }, { "cell_type": "code", "collapsed": false, "input": [ "# Algunas de las cosas anteriores se pueden realizar sin usar los m\u00e9todos .ix() o .xs()\n", "print(df['velocidad'][1:3])" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "segundo -0.133466\n", "tercero -0.418224\n", "Name: velocidad, dtype: float64\n" ] } ], "prompt_number": 29 }, { "cell_type": "code", "collapsed": false, "input": [ "# Da igual si colocamos el slice primero y despu\u00e9s las columnas:\n", "df['velocidad'][1:3] == df[1:3]['velocidad']" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 30, "text": [ "segundo True\n", "tercero True\n", "Name: velocidad, dtype: bool" ] } ], "prompt_number": 30 }, { "cell_type": "markdown", "metadata": {}, "source": [ "En lo anterior he estado usando los m\u00e9todos `.ix()`, `.xs()` para obtener [partes del DataFrame](http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-advanced). Son [herramientas muy flexibles que nos permiten acceder a los datos de forma muy personalizada](http://pandas.pydata.org/pandas-docs/stable/indexing.html#different-choices-for-indexing-loc-iloc-and-ix). Otras opciones ser\u00eda usar los m\u00e9todos `.loc()`, `.iloc()`, [`.select()`](http://pandas.pydata.org/pandas-docs/stable/indexing.html#the-select-method)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Es importante tener en cuenta que las series devueltas cuando se indexa un `DataFrame` son solo vistas y no una copia de los propios datos. Por tanto, debes ser precavido cuando manipulas los datos (al igual que sucede con los `numpy` arrays y otros tipos de datos). Lo siguiente (hecho con `numpy` arrays) es equivalente para las estructuras de datos de Pandas." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# Vista, \u00a1Cuidado!\n", "a = np.random.rand(5)\n", "data = a[0:2]\n", "data[:] = -999\n", "print(a)\n", "\n", "# Copias\n", "a = np.random.rand(5)\n", "data = a[0:2].copy()\n", "data[:] = -999\n", "print(a)\n", "\n", "a = np.random.rand(5)\n", "data = 1 * a[0:2]\n", "data[:] = -999\n", "print(a)\n", "\n", "a = np.random.rand(5)\n", "np.copyto(data, a[0:2]) # En este caso, data tiene que existir\n", "data[:] = -999\n", "print(a)\n", "\n", "a = np.random.rand(5)\n", "data = np.array(a[0:2])\n", "data[:] = -999\n", "print(a)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[ -9.99000000e+02 -9.99000000e+02 7.18723608e-01 5.30962716e-01\n", " 3.43706883e-01]\n", "[ 0.20812195 0.36386055 0.17570252 0.31071035 0.38838464]\n", "[ 0.37175682 0.36962863 0.14481144 0.80786818 0.82803089]\n", "[ 0.89958739 0.00190588 0.14769624 0.3378831 0.74536315]\n", "[ 0.19285654 0.51489647 0.19612007 0.52342758 0.2006809 ]\n" ] } ], "prompt_number": 31 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Para acceder a los valores de los \u00edndices podemos usar `.index`." ] }, { "cell_type": "code", "collapsed": false, "input": [ "df.index" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 32, "text": [ "Index(['primero', 'segundo', 'tercero', 'cuarto', 'quinto'], dtype='object')" ] } ], "prompt_number": 32 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Para acceder a los valores de las columnas podemos usar `.columns`." ] }, { "cell_type": "code", "collapsed": false, "input": [ "df.columns" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 33, "text": [ "Index(['velocidad', 'temperatura', 'presion', 'velocidad_maxima'], dtype='object')" ] } ], "prompt_number": 33 }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Concatenando (concatenate) y uniendo (merge/join) datos." ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Concatenar" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Para concatenar ficheros se usa la funci\u00f3n `pd.concat` ([documentaci\u00f3n oficial](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.tools.merge.concat.html#pandas.tools.merge.concat)]. Un ejemplo r\u00e1pido ser\u00eda el siguiente:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "datos1 = pd.DataFrame(np.random.randn(5,3))\n", "datos2 = pd.DataFrame(np.random.randn(5,3))\n", "piezas = [datos1, datos2]\n", "datos_concatenados_a = pd.concat(piezas)\n", "print('datos1\\n {}'.format(datos1))\n", "print('datos2\\n {}'.format(datos2))\n", "print('datos_concatenados\\n {}'.format(datos_concatenados_a))" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "datos1\n", " 0 1 2\n", "0 -1.691985 -1.181241 -0.714437\n", "1 0.955094 -0.238498 1.137918\n", "2 -0.533739 -0.285976 -0.990184\n", "3 -0.626446 0.664830 0.278803\n", "4 -0.183818 -0.013190 0.505786\n", "\n", "[5 rows x 3 columns]\n", "datos2\n", " 0 1 2\n", "0 -2.063044 2.328388 0.043275\n", "1 -1.720170 -0.039871 0.954244\n", "2 -0.173751 0.047003 -0.979577\n", "3 -0.293044 1.928332 -1.323554\n", "4 0.705127 3.711652 -0.535096\n", "\n", "[5 rows x 3 columns]\n", "datos_concatenados\n", " 0 1 2\n", "0 -1.691985 -1.181241 -0.714437\n", "1 0.955094 -0.238498 1.137918\n", "2 -0.533739 -0.285976 -0.990184\n", "3 -0.626446 0.664830 0.278803\n", "4 -0.183818 -0.013190 0.505786\n", "0 -2.063044 2.328388 0.043275\n", "1 -1.720170 -0.039871 0.954244\n", "2 -0.173751 0.047003 -0.979577\n", "3 -0.293044 1.928332 -1.323554\n", "4 0.705127 3.711652 -0.535096\n", "\n", "[10 rows x 3 columns]" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n" ] } ], "prompt_number": 34 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Interesante, r\u00e1pido y limpio, como me gusta. Pero, si nos fijamos, tenemos un problema con los \u00edndices ya que algunos est\u00e1n repetidos. Si accedemos al \u00edndice *0*, por ejemplo, obtendr\u00edamos dos filas de valores en lugar de una." ] }, { "cell_type": "code", "collapsed": false, "input": [ "datos_concatenados_a.ix[0]" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
012
0-1.691985-1.181241-0.714437
0-2.063044 2.328388 0.043275
\n", "

2 rows \u00d7 3 columns

\n", "
" ], "metadata": {}, "output_type": "pyout", "prompt_number": 35, "text": [ " 0 1 2\n", "0 -1.691985 -1.181241 -0.714437\n", "0 -2.063044 2.328388 0.043275\n", "\n", "[2 rows x 3 columns]" ] } ], "prompt_number": 35 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Lo anterior podr\u00eda llevar a equ\u00edvocos. Esto lo podemos solventar de varias formas. Una ser\u00eda reescribiendo la columna de \u00edndices para que no haya malentendidos al hacer cualquier operaci\u00f3n. Por ejemplo:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "datos_concatenados_aa = datos_concatenados_a\n", "datos_concatenados_aa.index = range(datos_concatenados_aa.shape[0])\n", "print('datos_concatenados\\n {}'.format(datos_concatenados_aa))" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "datos_concatenados\n", " 0 1 2\n", "0 -1.691985 -1.181241 -0.714437\n", "1 0.955094 -0.238498 1.137918\n", "2 -0.533739 -0.285976 -0.990184\n", "3 -0.626446 0.664830 0.278803\n", "4 -0.183818 -0.013190 0.505786\n", "5 -2.063044 2.328388 0.043275\n", "6 -1.720170 -0.039871 0.954244\n", "7 -0.173751 0.047003 -0.979577\n", "8 -0.293044 1.928332 -1.323554\n", "9 0.705127 3.711652 -0.535096\n", "\n", "[10 rows x 3 columns]\n" ] } ], "prompt_number": 36 }, { "cell_type": "markdown", "metadata": {}, "source": [ "O usando la palabra clave `ignore_index` pas\u00e1ndole el valor `True` al crear la concatenaci\u00f3n. Por ejemplo:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "datos_concatenados_aa = pd.concat(piezas, ignore_index = True)\n", "print(datos_concatenados_aa)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ " 0 1 2\n", "0 -1.691985 -1.181241 -0.714437\n", "1 0.955094 -0.238498 1.137918\n", "2 -0.533739 -0.285976 -0.990184\n", "3 -0.626446 0.664830 0.278803\n", "4 -0.183818 -0.013190 0.505786\n", "5 -2.063044 2.328388 0.043275\n", "6 -1.720170 -0.039871 0.954244\n", "7 -0.173751 0.047003 -0.979577\n", "8 -0.293044 1.928332 -1.323554\n", "9 0.705127 3.711652 -0.535096\n", "\n", "[10 rows x 3 columns]\n" ] } ], "prompt_number": 37 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Vale, hemos solventado el anterior problema pero que pasa si, por la raz\u00f3n que sea, nos interesase conservar los \u00edndices originales. Podr\u00edamos usar palabras clave para cada 'cosa' concatenada en el *DataFrame* final. Ejemplo: " ] }, { "cell_type": "code", "collapsed": false, "input": [ "#datos1 = pd.DataFrame(np.random.randn(5,3))\n", "#datos2 = pd.DataFrame(np.random.randn(5,3))\n", "#piezas = [datos1, datos2]\n", "datos_concatenados_b = pd.concat(piezas, keys = ['datos1', 'datos2'])\n", "print('datos1\\n {}'.format(datos1))\n", "print('datos2\\n {}'.format(datos2))\n", "print('datos_concatenados\\n {}'.format(datos_concatenados_b))" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "datos1\n", " 0 1 2\n", "0 -1.691985 -1.181241 -0.714437\n", "1 0.955094 -0.238498 1.137918\n", "2 -0.533739 -0.285976 -0.990184\n", "3 -0.626446 0.664830 0.278803\n", "4 -0.183818 -0.013190 0.505786\n", "\n", "[5 rows x 3 columns]\n", "datos2\n", " 0 1 2\n", "0 -2.063044 2.328388 0.043275\n", "1 -1.720170 -0.039871 0.954244\n", "2 -0.173751 0.047003 -0.979577\n", "3 -0.293044 1.928332 -1.323554\n", "4 0.705127 3.711652 -0.535096\n", "\n", "[5 rows x 3 columns]\n", "datos_concatenados\n", " 0 1 2\n", "datos1 0 -1.691985 -1.181241 -0.714437\n", " 1 0.955094 -0.238498 1.137918\n", " 2 -0.533739 -0.285976 -0.990184\n", " 3 -0.626446 0.664830 0.278803\n", " 4 -0.183818 -0.013190 0.505786\n", "datos2 0 -2.063044 2.328388 0.043275\n", " 1 -1.720170 -0.039871 0.954244\n", " 2 -0.173751 0.047003 -0.979577\n", " 3 -0.293044 1.928332 -1.323554\n", " 4 0.705127 3.711652 -0.535096\n", "\n", "[10 rows x 3 columns]" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n" ] } ], "prompt_number": 38 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Vemos que hay \u00edndices repetidos pero est\u00e1n en 'grupos' diferentes. De esta forma, si queremos acceder a la fila con \u00edndice 0 del primer grupo de datos concatenados (datos1) podemos hacer lo siguiente:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "print(datos_concatenados_b.ix['datos1'].ix[0])" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "0 -1.691985\n", "1 -1.181241\n", "2 -0.714437\n", "Name: 0, dtype: float64\n" ] } ], "prompt_number": 39 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Estamos viendo filas, pero podemos hacer los mismo para las columnas, por supuesto, usando el nombre de la columna (en el ejemplo siguiente, la columna `0`):" ] }, { "cell_type": "code", "collapsed": false, "input": [ "print(datos_concatenados_b.ix['datos1'][0])" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "0 -1.691985\n", "1 0.955094\n", "2 -0.533739\n", "3 -0.626446\n", "4 -0.183818\n", "Name: 0, dtype: float64\n" ] } ], "prompt_number": 40 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Vemos qu\u00e9 tipo de \u00edndice es este \u00edndice 'compuesto' que hemos creado:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "datos_concatenados_b.index" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 41, "text": [ "MultiIndex(levels=[['datos1', 'datos2'], [0, 1, 2, 3, 4]],\n", " labels=[[0, 0, 0, 0, 0, 1, 1, 1, 1, 1], [0, 1, 2, 3, 4, 0, 1, 2, 3, 4]])" ] } ], "prompt_number": 41 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Vemos que es un `MultiIndex`. No vamos a ver mucho m\u00e1s pero os lo dejo anotado para que sep\u00e1is que existen combinaciones de \u00edndices (o de columnas) y se manejan de forma un poco m\u00e1s compleja que un \u00edndice 'simple'. Se conoce como [indexaci\u00f3n jer\u00e1rquica](http://pandas.pydata.org/pandas-docs/stable/indexing.html#hierarchical-indexing-multiindex) y permiten ser un poco m\u00e1s descriptivos (verbose) con nuestros DataFrames aunque conlleva un punto m\u00e1s de complejidad a la hora de trabajar con los datos." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\u00bfQu\u00e9 pasa cuando una de las columnas no es igual en los grupos de datos que queramos concatenar? El nuevo `DataFrame` tendr\u00e1 en cuenta este aspecto rellenando con `NaNs` donde convenga. Veamos el siguiente c\u00f3digo de ejemplo:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "datos1 = pd.DataFrame(np.random.randn(5,3))\n", "datos2 = pd.DataFrame(np.random.randn(5,4))\n", "piezas = [datos1, datos2]\n", "datos_concatenados_c = pd.concat(piezas, ignore_index = True)\n", "print('datos1\\n {}'.format(datos1))\n", "print('datos2\\n {}'.format(datos2))\n", "print('datos_concatenados\\n {}'.format(datos_concatenados_c))" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "datos1\n", " 0 1 2\n", "0 -0.082729 -0.016452 -1.280156\n", "1 0.606336 -0.504770 -2.017690\n", "2 -2.147009 -0.632275 0.023689\n", "3 -0.255461 -0.042007 0.661835\n", "4 2.351576 0.735611 -0.187072\n", "\n", "[5 rows x 3 columns]\n", "datos2\n", " 0 1 2 3\n", "0 -0.223023 0.070622 -0.577119 -1.430177\n", "1 -1.661289 -0.214221 0.709818 -0.642611\n", "2 -0.098368 -0.489105 -1.373906 -2.104431\n", "3 0.880578 -0.601151 -1.450542 -0.289738\n", "4 -1.461346 -0.539262 0.327825 -0.944431\n", "\n", "[5 rows x 4 columns]\n", "datos_concatenados\n", " 0 1 2 3\n", "0 -0.082729 -0.016452 -1.280156 NaN\n", "1 0.606336 -0.504770 -2.017690 NaN\n", "2 -2.147009 -0.632275 0.023689 NaN\n", "3 -0.255461 -0.042007 0.661835 NaN\n", "4 2.351576 0.735611 -0.187072 NaN\n", "5 -0.223023 0.070622 -0.577119 -1.430177\n", "6 -1.661289 -0.214221 0.709818 -0.642611\n", "7 -0.098368 -0.489105 -1.373906 -2.104431\n", "8 0.880578 -0.601151 -1.450542 -0.289738\n", "9 -1.461346 -0.539262 0.327825 -0.944431\n", "\n", "[10 rows x 4 columns]" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n" ] } ], "prompt_number": 42 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Vemos que el primer grupo de datos, datos1, solo tiene tres columnas mientras que el segundo grupo, datos2, tiene 4 columnas. El resultado final tendr\u00e1 en cuenta esto y rellener\u00e1 la columna 3 que pertenece a los datos del primer grupo de datos, datos1. Cool!\n", "\n", "Lo visto hasta ahora para concatenar *Series* o *DataFrames* lo podemos hacer tambi\u00e9n usando el m\u00e9todo `append`. Veamos un ejemplo similar a lo anterior:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "datos1 = pd.DataFrame(np.random.randn(5,3))\n", "datos2 = pd.DataFrame(np.random.randn(5,4))\n", "datos_concatenados_d = datos1.append(datos2, ignore_index = True)\n", "print('datos1\\n {}'.format(datos1))\n", "print('datos2\\n {}'.format(datos2))\n", "print('datos_concatenados\\n {}'.format(datos_concatenados_d))" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "datos1\n", " 0 1 2\n", "0 -0.974367 1.732370 0.354479\n", "1 -0.021746 2.215287 1.107243\n", "2 0.018506 1.301015 1.103651\n", "3 -1.857281 -1.181981 0.097104\n", "4 -0.595689 0.140885 1.993213\n", "\n", "[5 rows x 3 columns]\n", "datos2\n", " 0 1 2 3\n", "0 -0.211180 -0.093403 0.215210 -0.154284\n", "1 0.206997 1.277379 -0.893895 -0.216731\n", "2 -1.138390 -0.067240 1.688928 -2.191215\n", "3 0.938069 0.174496 -1.722735 -0.873746\n", "4 0.177425 0.823896 -0.595673 -0.426416\n", "\n", "[5 rows x 4 columns]\n", "datos_concatenados\n", " 0 1 2 3\n", "0 -0.974367 1.732370 0.354479 NaN\n", "1 -0.021746 2.215287 1.107243 NaN\n", "2 0.018506 1.301015 1.103651 NaN\n", "3 -1.857281 -1.181981 0.097104 NaN\n", "4 -0.595689 0.140885 1.993213 NaN\n", "5 -0.211180 -0.093403 0.215210 -0.154284\n", "6 0.206997 1.277379 -0.893895 -0.216731\n", "7 -1.138390 -0.067240 1.688928 -2.191215\n", "8 0.938069 0.174496 -1.722735 -0.873746\n", "9 0.177425 0.823896 -0.595673 -0.426416\n", "\n", "[10 rows x 4 columns]" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n" ] } ], "prompt_number": 43 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Unir (merge/join)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pandas dispone de la funci\u00f3n `merge` ([documentaci\u00f3n oficial](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.tools.merge.merge.html#pandas.tools.merge.merge)) que permite 'unir' datos al estilo de como se hace con bases de datos relacionales (usando **SQL**). Tambi\u00e9n se puede acceder al m\u00e9todo `merge` disponible en las instancias a un *Dataframe*.\n", "\n", "Por su parte, `join` es un m\u00e9todo disponible en un *DataFrame* y sirve para hacer uniones de \u00edndices sobre \u00edndices o de \u00edndices sobre columnas. Las uniones que hace `join` las hace sobre los \u00edndices, en lugar de hacerlo sobre columnas comunes como se hace con `merge`. A ver si viendo los ejemplos queda un poco mejor este \u00faltimo p\u00e1rrafo y las diferencias entre `join` y `merge`.\n", "\n", "Las uniones pueden ser *uno-a-uno*, *muchos-a-uno* o *muchos-a-muchos*.\n", "\n", "Una uni\u00f3n *uno-a-uno* ser\u00eda cuando unimos dos tablas (*DataFrames*) con \u00edndices \u00fanicos como hemos hecho en el apartado anterior con las concatenaciones." ] }, { "cell_type": "code", "collapsed": false, "input": [ "datos1 = pd.DataFrame(np.random.randn(10), columns = ['columna1'])\n", "datos2 = pd.DataFrame(np.random.randn(14), columns = ['columna2'], index = np.arange(1,15))\n", "datos1j = datos1.join(datos2)\n", "datos2j = datos2.join(datos1)\n", "print('datos1j \\n{}\\n'.format(datos1j))\n", "print('datos2j \\n{}'.format(datos2j))" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "datos1j \n", " columna1 columna2\n", "0 -0.209303 NaN\n", "1 -0.430892 1.052453\n", "2 0.766200 -0.346896\n", "3 1.773694 -0.249700\n", "4 -2.259187 -0.588739\n", "5 -0.930647 0.160590\n", "6 0.029990 0.421446\n", "7 0.812770 -0.315913\n", "8 0.681786 0.256745\n", "9 -0.115109 0.524278\n", "\n", "[10 rows x 2 columns]\n", "\n", "datos2j \n", " columna2 columna1\n", "1 1.052453 -0.430892\n", "2 -0.346896 0.766200\n", "3 -0.249700 1.773694\n", "4 -0.588739 -2.259187\n", "5 0.160590 -0.930647\n", "6 0.421446 0.029990\n", "7 -0.315913 0.812770\n", "8 0.256745 0.681786\n", "9 0.524278 -0.115109\n", "10 -1.707269 NaN\n", "11 -1.140342 NaN\n", "12 -1.751337 NaN\n", "13 -0.481319 NaN\n", "14 1.604800 NaN\n", "\n", "[14 rows x 2 columns]\n" ] } ], "prompt_number": 44 }, { "cell_type": "markdown", "metadata": {}, "source": [ "En los anteriores ejemplos, `datos1j` es el resultado de unir los datos `datos2` a los datos `datos1` en todos los \u00edndices comunes que tienen ambos teniendo solo en cuenta el rango de \u00edndices definido en `datos1`. Si alg\u00fan dato en `datos2` no tiene un \u00edndice presente en `datos1` se rellenar\u00e1 con un `NaN`. Con `datos2j` sucede lo mismo que con `datos1j` lo que el \u00edndice que tiene relevancia ahora es el perteneciente a `datos2j`. No s\u00e9 si habr\u00e1 quedado m\u00e1s o menos claro.\n", "\n", "Ahora vamos a unir pero usando la palabra clave `how` que nos permite decir como se van a tener en cuenta los \u00edndices. Normalmente le pasaremos el par\u00e1metro `outer` o `inner`. El primero, `outer`, indica que los \u00edndices de los *DataFrames* se unen como en una uni\u00f3n de conjuntos, el segundo, `inner`, une los \u00edndices como si hici\u00e9ramos una intersecci\u00f3n de conjuntos. Veamos un par de ejemplos para que se vea de forma pr\u00e1ctica, el primero usando `outer` y el segundo usando `inner`:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "datos3j1 = datos1.join(datos2, how = 'outer')\n", "datos3j2 = datos2.join(datos1, how = 'outer')\n", "print('datos3j1 \\n{}\\n'.format(datos3j1))\n", "print('datos3j2 recolocados\\n{}\\n'.format(datos3j2.ix[:, ['columna1','columna2']]))\n", "print('datos3j2 \\n{}'.format(datos3j2))" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "datos3j1 \n", " columna1 columna2\n", "0 -0.209303 NaN\n", "1 -0.430892 1.052453\n", "2 0.766200 -0.346896\n", "3 1.773694 -0.249700\n", "4 -2.259187 -0.588739\n", "5 -0.930647 0.160590\n", "6 0.029990 0.421446\n", "7 0.812770 -0.315913\n", "8 0.681786 0.256745\n", "9 -0.115109 0.524278\n", "10 NaN -1.707269\n", "11 NaN -1.140342\n", "12 NaN -1.751337\n", "13 NaN -0.481319\n", "14 NaN 1.604800\n", "\n", "[15 rows x 2 columns]\n", "\n", "datos3j2 recolocados\n", " columna1 columna2\n", "0 -0.209303 NaN\n", "1 -0.430892 1.052453\n", "2 0.766200 -0.346896\n", "3 1.773694 -0.249700\n", "4 -2.259187 -0.588739\n", "5 -0.930647 0.160590\n", "6 0.029990 0.421446\n", "7 0.812770 -0.315913\n", "8 0.681786 0.256745\n", "9 -0.115109 0.524278\n", "10 NaN -1.707269\n", "11 NaN -1.140342\n", "12 NaN -1.751337\n", "13 NaN -0.481319\n", "14 NaN 1.604800\n", "\n", "[15 rows x 2 columns]\n", "\n", "datos3j2 \n", " columna2 columna1\n", "0 NaN -0.209303\n", "1 1.052453 -0.430892\n", "2 -0.346896 0.766200\n", "3 -0.249700 1.773694\n", "4 -0.588739 -2.259187\n", "5 0.160590 -0.930647\n", "6 0.421446 0.029990\n", "7 -0.315913 0.812770\n", "8 0.256745 0.681786\n", "9 0.524278 -0.115109\n", "10 -1.707269 NaN\n", "11 -1.140342 NaN\n", "12 -1.751337 NaN\n", "13 -0.481319 NaN\n", "14 1.604800 NaN\n", "\n", "[15 rows x 2 columns]" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n" ] } ], "prompt_number": 45 }, { "cell_type": "code", "collapsed": false, "input": [ "datos4j1 = datos1.join(datos2, how = 'inner')\n", "datos4j2 = datos2.join(datos1, how = 'inner')\n", "print('datos4j1 \\n{}\\n'.format(datos4j1))\n", "print('datos4j2 recolocados\\n{}\\n'.format(datos4j2.ix[:, ['columna1','columna2']]))\n", "print('datos4j2 \\n{}'.format(datos4j2))" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "datos4j1 \n", " columna1 columna2\n", "1 -0.430892 1.052453\n", "2 0.766200 -0.346896\n", "3 1.773694 -0.249700\n", "4 -2.259187 -0.588739\n", "5 -0.930647 0.160590\n", "6 0.029990 0.421446\n", "7 0.812770 -0.315913\n", "8 0.681786 0.256745\n", "9 -0.115109 0.524278\n", "\n", "[9 rows x 2 columns]\n", "\n", "datos4j2 recolocados\n", " columna1 columna2\n", "1 -0.430892 1.052453\n", "2 0.766200 -0.346896\n", "3 1.773694 -0.249700\n", "4 -2.259187 -0.588739\n", "5 -0.930647 0.160590\n", "6 0.029990 0.421446\n", "7 0.812770 -0.315913\n", "8 0.681786 0.256745\n", "9 -0.115109 0.524278\n", "\n", "[9 rows x 2 columns]\n", "\n", "datos4j2 \n", " columna2 columna1\n", "1 1.052453 -0.430892\n", "2 -0.346896 0.766200\n", "3 -0.249700 1.773694\n", "4 -0.588739 -2.259187\n", "5 0.160590 -0.930647\n", "6 0.421446 0.029990\n", "7 -0.315913 0.812770\n", "8 0.256745 0.681786\n", "9 0.524278 -0.115109\n", "\n", "[9 rows x 2 columns]" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n" ] } ], "prompt_number": 46 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Todo lo anterior se puede hacer tambi\u00e9n usando la funci\u00f3n o m\u00e9todo `merge` pero encuentro que es una forma un poco m\u00e1s rebuscada por lo que no la vamos a mostrar aqu\u00ed ya que a\u00f1ade complejidad. Veremos usos de `merge` m\u00e1s adelante." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ahora vamos a mostrar una uni\u00f3n *muchos-a-uno*. Estas uniones se hacen sobre una o m\u00e1s columnas como referencia, no a partir de \u00edndices, por lo que los valores contenidos pueden no ser \u00fanicos. Como siempre, vamos a ver un poco de c\u00f3digo para ver si clarifica un poco m\u00e1s la teor\u00eda:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "datos1 = pd.DataFrame(np.random.randn(10), columns = ['columna1'])\n", "datos1['otra_columna'] = ['hola', 'mundo'] * 5\n", "datos2 = pd.DataFrame(np.random.randn(2,2), columns = ['col1', 'col2'], index = ['hola', 'mundo'])\n", "print('datos1 \\n {} \\n'.format(datos1))\n", "print('datos2 \\n {} \\n'.format(datos2))\n", "print(u'Uni\u00f3n de datos \\n {} \\n'.format(datos1.join(datos2, on = 'otra_columna')))" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "datos1 \n", " columna1 otra_columna\n", "0 -2.086230 hola\n", "1 -1.015736 mundo\n", "2 -0.919460 hola\n", "3 0.923531 mundo\n", "4 -0.445977 hola\n", "5 0.719787 mundo\n", "6 1.064480 hola\n", "7 -0.235803 mundo\n", "8 1.395844 hola\n", "9 1.492875 mundo\n", "\n", "[10 rows x 2 columns] \n", "\n", "datos2 \n", " col1 col2\n", "hola 0.400267 -0.678126\n", "mundo 0.855735 0.619193\n", "\n", "[2 rows x 2 columns] \n", "\n", "Uni\u00f3n de datos \n", " columna1 otra_columna col1 col2\n", "0 -2.086230 hola 0.400267 -0.678126\n", "1 -1.015736 mundo 0.855735 0.619193\n", "2 -0.919460 hola 0.400267 -0.678126\n", "3 0.923531 mundo 0.855735 0.619193\n", "4 -0.445977 hola 0.400267 -0.678126\n", "5 0.719787 mundo 0.855735 0.619193\n", "6 1.064480 hola 0.400267 -0.678126\n", "7 -0.235803 mundo 0.855735 0.619193\n", "8 1.395844 hola 0.400267 -0.678126\n", "9 1.492875 mundo 0.855735 0.619193\n", "\n", "[10 rows x 4 columns] \n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n" ] } ], "prompt_number": 47 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Estamos uniendo sobre los valores de la columna del DataFrame `datos1` que presenta valores presentes en los \u00edndices del DataFrame `datos2`. En el anterior ejemplo hemos unido teniendo en cuenta una \u00fanica columna, si queremos unir teniendo en cuenta varias columnas, el DataFrame que se le pase deber\u00e1 presentar un Multi\u00cdndice con tantos \u00edndices como columnas usemos ([ver documentaci\u00f3n sobre Multi\u00cdndices](http://pandas.pydata.org/pandas-docs/stable/indexing.html#hierarchical-indexing-multiindex) y [sobre uni\u00f3n con ellos](http://pandas.pydata.org/pandas-docs/stable/merging.html#joining-key-columns-on-an-index))." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Para hacer uniones de *muchos-a-muchos* usaremos `merge` que ofrece mayor libertad para poder hacer uniones de cualquier tipo (tambi\u00e9n las que hemos visto hasta ahora de *uno-a-uno* y de *muchos-a-uno*)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "En el siguiente ejemplo vamos a hacer una uni\u00f3n de dos DataFrames usando `merge` y luego iremos explicando lo que hemos estado haciendo poco a poco para ver si se entiende un poco mejor." ] }, { "cell_type": "code", "collapsed": false, "input": [ "datos_dcha = pd.DataFrame({'clave': ['foo'] * 3, 'valor_dcha': np.arange(3)})\n", "datos_izda = pd.DataFrame({'clave': ['foo'] * 3, 'valor_izda': np.arange(5, 8)})\n", "datos_unidos = pd.merge(datos_izda, datos_dcha, on = 'clave')\n", "print('datos_dcha \\n {} \\n'.format(datos_dcha))\n", "print('datos_izda \\n {} \\n'.format(datos_izda))\n", "print('datos_unidos \\n {}'.format(datos_unidos))" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "datos_dcha \n", " clave valor_dcha\n", "0 foo 0\n", "1 foo 1\n", "2 foo 2\n", "\n", "[3 rows x 2 columns] \n", "\n", "datos_izda \n", " clave valor_izda\n", "0 foo 5\n", "1 foo 6\n", "2 foo 7\n", "\n", "[3 rows x 2 columns] \n", "\n", "datos_unidos \n", " clave valor_izda valor_dcha\n", "0 foo 5 0\n", "1 foo 5 1\n", "2 foo 5 2\n", "3 foo 6 0\n", "4 foo 6 1\n", "5 foo 6 2\n", "6 foo 7 0\n", "7 foo 7 1\n", "8 foo 7 2\n", "\n", "[9 rows x 3 columns]" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n" ] } ], "prompt_number": 48 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Vemos que si hacemos una uni\u00f3n de la anterior forma, a cada valor de `datos_dcha` le 'asocia' cada uno de los valores de `datos_izda` que tengan la misma clave. En la siquiente celda de c\u00f3digo vemos otro ejemplo de lo anterior un poco m\u00e1s completo teniendo en cuenta dos columnas de claves y usando el m\u00e9todo `outer` de 'uni\u00f3n':" ] }, { "cell_type": "code", "collapsed": false, "input": [ "datos_dcha = pd.DataFrame({'clave1': ['foo', 'foo', 'bar', 'bar'],\n", " 'clave2': ['one', 'one', 'one', 'two'],\n", " 'val_dcha': [4, 5, 6, 7]})\n", "datos_izda = pd.DataFrame({'clave1': ['foo', 'foo', 'bar'],\n", " 'clave2': ['one', 'two', 'one'],\n", " 'val_izda': [1, 2, 3]})\n", "datos_unidos = pd.merge(datos_izda, datos_dcha, how='outer')\n", "print('datos_dcha \\n {} \\n'.format(datos_dcha))\n", "print('datos_izda \\n {} \\n'.format(datos_izda))\n", "print('datos_unidos \\n {}'.format(datos_unidos))" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "datos_dcha \n", " clave1 clave2 val_dcha\n", "0 foo one 4\n", "1 foo one 5\n", "2 bar one 6\n", "3 bar two 7\n", "\n", "[4 rows x 3 columns] \n", "\n", "datos_izda \n", " clave1 clave2 val_izda\n", "0 foo one 1\n", "1 foo two 2\n", "2 bar one 3\n", "\n", "[3 rows x 3 columns] \n", "\n", "datos_unidos \n", " clave1 clave2 val_izda val_dcha\n", "0 foo one 1 4\n", "1 foo one 1 5\n", "2 foo two 2 NaN\n", "3 bar one 3 6\n", "4 bar two NaN 7\n", "\n", "[5 rows x 4 columns]" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n" ] } ], "prompt_number": 49 }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Y mucho m\u00e1s" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Esto solo ha sido un peque\u00f1o vistazo con cosas que considero importantes pero que no tienen que ser las m\u00e1s importantes. Pod\u00e9is echarle un ojo a:\n", "\n", "* `sort, max, min, head, tail, unique, groupby, apply, transform, stack, unstack, mean, std, isnull, value_counts, notnull, rank, dropna, fillna, describe, cov, corr, duplicated, drop, pivot, pivot_table, drop_duplicates, quantile`,...\n", "\n", "para seguir viendo cosas \u00fatiles." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "___________________________________________" ] }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Analizando datos (si queda tiempo e inter\u00e9s...)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Adem\u00e1s de permitirnos indexar, mover, eliminar,..., datos de formas muy diferentes tambi\u00e9n podemos usar Pandas para hacer an\u00e1lisis de datos. En este sentido es como un `numpy` supervitaminado y supermineralizado (si quer\u00e9is hacer an\u00e1lisis est\u00e1distico m\u00e1s complejo le pod\u00e9is echar un vistazo a [statsmodels](http://statsmodels.sourceforge.net/), [scikit-learn](http://scikit-learn.org/stable/),...\n", "\n", "Vamos a usar unos datos que me he descargado de [la p\u00e1gina del INE](http://www.ine.es/daco/daco42/nombyapel/nombyapel.htm). Los he dejado en formato excel para que veamos como tambi\u00e9n podemos leer datos excel." ] }, { "cell_type": "code", "collapsed": false, "input": [ "nenas = pd.read_excel('nombres_recien_nacidos.xlsx', 'Ni\u00f1as', header = 1, skiprows = 1)\n", "nenes = pd.read_excel('nombres_recien_nacidos.xlsx', 'Ni\u00f1os', header = 1, skiprows = 1)" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 51 }, { "cell_type": "code", "collapsed": false, "input": [ "nenas.head(5)" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
nombrenumeronombre.1numero.1nombre.2numero.2nombre.3numero.3nombre.4numero.4nombre.5numero.5nombre.6numero.6nombre.7numero.7nombre.8numero.8nombre.9numero.9
0 LUCIA 6363 LUCIA 6143 LUCIA 6624 LUCIA 6847 LUCIA 8013 LUCIA 8192 LUCIA 9454 LUCIA 10146 LUCIA 10370 LUCIA 9035...
1 MARIA 5823 PAULA 5462 PAULA 5859 PAULA 6549 MARIA 6883 MARIA 6927 MARIA 7702 MARIA 7784 MARIA 7865 MARIA 8709...
2 PAULA 5375 MARIA 5339 MARIA 5767 MARIA 6113 PAULA 6806 PAULA 6402 PAULA 6516 PAULA 6684 PAULA 7147 PAULA 7003...
3 DANIELA 4748 SARA 4345 DANIELA 4680 SARA 4417 SARA 4730 SARA 4606 LAURA 5144 LAURA 5276 LAURA 5638 LAURA 5451...
4 SARA 4456 DANIELA 4270 SARA 4662 DANIELA 4279 CARLA 4271 LAURA 4335 CLAUDIA 4756 MARTA 4592 MARTA 4583 MARTA 4608...
\n", "

5 rows \u00d7 22 columns

\n", "
" ], "metadata": {}, "output_type": "pyout", "prompt_number": 52, "text": [ " nombre numero nombre.1 numero.1 nombre.2 numero.2 nombre.3 numero.3 \\\n", "0 LUCIA 6363 LUCIA 6143 LUCIA 6624 LUCIA 6847 \n", "1 MARIA 5823 PAULA 5462 PAULA 5859 PAULA 6549 \n", "2 PAULA 5375 MARIA 5339 MARIA 5767 MARIA 6113 \n", "3 DANIELA 4748 SARA 4345 DANIELA 4680 SARA 4417 \n", "4 SARA 4456 DANIELA 4270 SARA 4662 DANIELA 4279 \n", "\n", " nombre.4 numero.4 nombre.5 numero.5 nombre.6 numero.6 nombre.7 numero.7 \\\n", "0 LUCIA 8013 LUCIA 8192 LUCIA 9454 LUCIA 10146 \n", "1 MARIA 6883 MARIA 6927 MARIA 7702 MARIA 7784 \n", "2 PAULA 6806 PAULA 6402 PAULA 6516 PAULA 6684 \n", "3 SARA 4730 SARA 4606 LAURA 5144 LAURA 5276 \n", "4 CARLA 4271 LAURA 4335 CLAUDIA 4756 MARTA 4592 \n", "\n", " nombre.8 numero.8 nombre.9 numero.9 \n", "0 LUCIA 10370 LUCIA 9035 ... \n", "1 MARIA 7865 MARIA 8709 ... \n", "2 PAULA 7147 PAULA 7003 ... \n", "3 LAURA 5638 LAURA 5451 ... \n", "4 MARTA 4583 MARTA 4608 ... \n", "\n", "[5 rows x 22 columns]" ] } ], "prompt_number": 52 }, { "cell_type": "code", "collapsed": false, "input": [ "cols_1 = []\n", "for i in range(2012,2001,-1):\n", " cols_1.append((str(i),'nombre'))\n", " cols_1.append((str(i), 'numero'))\n", "cols = pd.MultiIndex.from_tuples(cols_1, names=['a\u00f1o','campo'])" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 56 }, { "cell_type": "code", "collapsed": false, "input": [ "nenes.columns = cols\n", "nenas.columns = cols\n", "nenes.index = range(1,101)\n", "nenas.index = range(1,101)" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 57 }, { "cell_type": "code", "collapsed": false, "input": [ "nenes.tail(5)" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
a\u00f1o2012201120102009200820072006200520042003
camponombrenumeronombrenumeronombrenumeronombrenumeronombrenumeronombrenumeronombrenumeronombrenumeronombrenumeronombrenumero
96 YERAY 517 GAEL 439 JUANJOSE 442 YERAY 458 JUANANTONIO 467 JUANANTONIO 465 BRUNO 478 ADAM 427 MIKEL 431 IZAN 397...
97 GAEL 501 YERAY 439 JON 436 JOSEMARIA 447 AIMAR 464 CESAR 461 SAUL 477 JON 419 MATEO 428 GUILLEM 385...
98 JON 493 JON 431 NIL 425 SERGI 447 ROGER 457 AIMAR 458 JUANCARLOS 472 MIKEL 415 DARIO 426 ABEL 380...
99 MIKEL 485 ANDER 419 ARTURO 419 MIKEL 444 JOAQUIN 446 ANDER 443 ROGER 469 FRANCISCOJOSE 413 ALFONSO 418 MARTI 376...
100 GUILLEM 479 JUANJOSE 418 JOAQUIN 419 KEVIN 440 JOSEMARIA 446 XAVIER 442 FRANCISCOJOSE 455 AIMAR 402 ANDER 416 MATEO 373...
\n", "

5 rows \u00d7 22 columns

\n", "
" ], "metadata": {}, "output_type": "pyout", "prompt_number": 58, "text": [ "a\u00f1o 2012 2012 2011 2011 2010 2010 2009 2009 \\\n", "campo nombre numero nombre numero nombre numero nombre numero \n", "96 YERAY 517 GAEL 439 JUANJOSE 442 YERAY 458 \n", "97 GAEL 501 YERAY 439 JON 436 JOSEMARIA 447 \n", "98 JON 493 JON 431 NIL 425 SERGI 447 \n", "99 MIKEL 485 ANDER 419 ARTURO 419 MIKEL 444 \n", "100 GUILLEM 479 JUANJOSE 418 JOAQUIN 419 KEVIN 440 \n", "\n", "a\u00f1o 2008 2008 2007 2007 2006 2006 \\\n", "campo nombre numero nombre numero nombre numero \n", "96 JUANANTONIO 467 JUANANTONIO 465 BRUNO 478 \n", "97 AIMAR 464 CESAR 461 SAUL 477 \n", "98 ROGER 457 AIMAR 458 JUANCARLOS 472 \n", "99 JOAQUIN 446 ANDER 443 ROGER 469 \n", "100 JOSEMARIA 446 XAVIER 442 FRANCISCOJOSE 455 \n", "\n", "a\u00f1o 2005 2005 2004 2004 2003 2003 \n", "campo nombre numero nombre numero nombre numero \n", "96 ADAM 427 MIKEL 431 IZAN 397 ... \n", "97 JON 419 MATEO 428 GUILLEM 385 ... \n", "98 MIKEL 415 DARIO 426 ABEL 380 ... \n", "99 FRANCISCOJOSE 413 ALFONSO 418 MARTI 376 ... \n", "100 AIMAR 402 ANDER 416 MATEO 373 ... \n", "\n", "[5 rows x 22 columns]" ] } ], "prompt_number": 58 }, { "cell_type": "code", "collapsed": false, "input": [ "nenas.T.xs('nombre', level = 'campo')" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
1234567891011121314151617181920
a\u00f1o
2012 LUCIA MARIA PAULA DANIELA SARA CARLA MARTINA SOFIA JULIA ALBA VALERIA CLAUDIA IRENE MARTA LAURA NOA CARMEN ADRIANA AINHOA ELENA...
2011 LUCIA PAULA MARIA SARA DANIELA CARLA SOFIA ALBA CLAUDIA MARTINA JULIA MARTA IRENE LAURA VALERIA CARMEN ADRIANA ELENA NOA ANA...
2010 LUCIA PAULA MARIA DANIELA SARA CARLA CLAUDIA SOFIA ALBA IRENE MARTA LAURA JULIA MARTINA CARMEN ADRIANA AITANA ELENA ANA NOA...
2009 LUCIA PAULA MARIA SARA DANIELA CARLA CLAUDIA MARTA IRENE SOFIA ALBA LAURA JULIA CARMEN MARTINA ANA AITANA ELENA ANDREA ADRIANA...
2008 LUCIA MARIA PAULA SARA CARLA CLAUDIA LAURA MARTA IRENE ALBA SOFIA DANIELA JULIA ANDREA ANA CARMEN ELENA NEREA NATALIA MARTINA...
2007 LUCIA MARIA PAULA SARA LAURA CLAUDIA IRENE MARTA ALBA CARLA ANDREA JULIA ANA SOFIA NEREA DANIELA NATALIA CARMEN ELENA ROCIO...
2006 LUCIA MARIA PAULA LAURA CLAUDIA IRENE MARTA ALBA SARA CARLA ANDREA NEREA JULIA NATALIA ELENA ANA SOFIA CARMEN DANIELA MARINA...
2005 LUCIA MARIA PAULA LAURA MARTA ALBA CLAUDIA CARLA ANDREA SARA NEREA IRENE ANA NATALIA JULIA ELENA CARMEN SOFIA MARINA CRISTINA...
2004 LUCIA MARIA PAULA LAURA MARTA ALBA ANDREA CLAUDIA SARA NEREA CARLA ANA NATALIA IRENE MARINA CRISTINA ELENA CARMEN JULIA AINHOA...
2003 LUCIA MARIA PAULA LAURA MARTA ANDREA ALBA SARA CLAUDIA ANA NEREA CARLA ELENA CRISTINA AINHOA NATALIA MARINA IRENE CARMEN NURIA...
2002 MARIA LUCIA PAULA LAURA MARTA ALBA ANDREA SARA ANA NEREA CLAUDIA MARINA CRISTINA ELENA IRENE NATALIA CARLA CARMEN NURIA AINHOA...
\n", "

11 rows \u00d7 100 columns

\n", "
" ], "metadata": {}, "output_type": "pyout", "prompt_number": 59, "text": [ " 1 2 3 4 5 6 7 8 \\\n", "a\u00f1o \n", "2012 LUCIA MARIA PAULA DANIELA SARA CARLA MARTINA SOFIA \n", "2011 LUCIA PAULA MARIA SARA DANIELA CARLA SOFIA ALBA \n", "2010 LUCIA PAULA MARIA DANIELA SARA CARLA CLAUDIA SOFIA \n", "2009 LUCIA PAULA MARIA SARA DANIELA CARLA CLAUDIA MARTA \n", "2008 LUCIA MARIA PAULA SARA CARLA CLAUDIA LAURA MARTA \n", "2007 LUCIA MARIA PAULA SARA LAURA CLAUDIA IRENE MARTA \n", "2006 LUCIA MARIA PAULA LAURA CLAUDIA IRENE MARTA ALBA \n", "2005 LUCIA MARIA PAULA LAURA MARTA ALBA CLAUDIA CARLA \n", "2004 LUCIA MARIA PAULA LAURA MARTA ALBA ANDREA CLAUDIA \n", "2003 LUCIA MARIA PAULA LAURA MARTA ANDREA ALBA SARA \n", "2002 MARIA LUCIA PAULA LAURA MARTA ALBA ANDREA SARA \n", "\n", " 9 10 11 12 13 14 15 \\\n", "a\u00f1o \n", "2012 JULIA ALBA VALERIA CLAUDIA IRENE MARTA LAURA \n", "2011 CLAUDIA MARTINA JULIA MARTA IRENE LAURA VALERIA \n", "2010 ALBA IRENE MARTA LAURA JULIA MARTINA CARMEN \n", "2009 IRENE SOFIA ALBA LAURA JULIA CARMEN MARTINA \n", "2008 IRENE ALBA SOFIA DANIELA JULIA ANDREA ANA \n", "2007 ALBA CARLA ANDREA JULIA ANA SOFIA NEREA \n", "2006 SARA CARLA ANDREA NEREA JULIA NATALIA ELENA \n", "2005 ANDREA SARA NEREA IRENE ANA NATALIA JULIA \n", "2004 SARA NEREA CARLA ANA NATALIA IRENE MARINA \n", "2003 CLAUDIA ANA NEREA CARLA ELENA CRISTINA AINHOA \n", "2002 ANA NEREA CLAUDIA MARINA CRISTINA ELENA IRENE \n", "\n", " 16 17 18 19 20 \n", "a\u00f1o \n", "2012 NOA CARMEN ADRIANA AINHOA ELENA ... \n", "2011 CARMEN ADRIANA ELENA NOA ANA ... \n", "2010 ADRIANA AITANA ELENA ANA NOA ... \n", "2009 ANA AITANA ELENA ANDREA ADRIANA ... \n", "2008 CARMEN ELENA NEREA NATALIA MARTINA ... \n", "2007 DANIELA NATALIA CARMEN ELENA ROCIO ... \n", "2006 ANA SOFIA CARMEN DANIELA MARINA ... \n", "2005 ELENA CARMEN SOFIA MARINA CRISTINA ... \n", "2004 CRISTINA ELENA CARMEN JULIA AINHOA ... \n", "2003 NATALIA MARINA IRENE CARMEN NURIA ... \n", "2002 NATALIA CARLA CARMEN NURIA AINHOA ... \n", "\n", "[11 rows x 100 columns]" ] } ], "prompt_number": 59 }, { "cell_type": "code", "collapsed": false, "input": [ "indices = nenas.T.xs('nombre', level = 'campo') == 'LUCIA'" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 60 }, { "cell_type": "code", "collapsed": false, "input": [ "plt.figure(figsize = (20,6))\n", "nenas.T.xs('numero',level = 'campo')[indices].sum().plot(kind='bar')\n", "print(nenas.T.xs('numero',level = 'campo')[indices].sum().sum())" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "88899.0\n" ] }, { "metadata": {}, "output_type": "display_data", "png": "iVBORw0KGgoAAAANSUhEUgAABI0AAAF3CAYAAAAo+bvsAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3X+cZXV95/lXQwcUoyCJAiraroFRJkYUo+5jonaiIpOd\niMkaxJ1k6cgjuwmZQGYzq5DMjJjZGDE7D1udweyMGsBVhMTE6AQJaLqczUwQYyiDAhFI2ggKOiLo\nOGNGtPeP77lTl0v9uKf7Fv3+fur1fDzqUfec+65T71un7+3qb5/v94IkSZIkSZIkSZIkSZIkSZIk\nSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSbHOA24EPj3cBjgauBb4LHANcNRU/gLgVuAW\n4NSp/acMx7kVeMvU/sOBK4b91wFPWvgjkCRJkiRJ0kJ9P22g52HAobSBoqcAbwJeM2ReC7xxuH0S\nsAx8F7ADuA3YNtx3PfCc4fZVwGnD7XOAi4fbrwTet/iHIUmSJEmSpEV6BfCOqe1/ShssugU4Zth3\n7LAN7Sqj107lrwaeBxwH3Dy1/0zgt6Yyzx1ubwe+vKDukiRJkiRJ2k+HbHD/p4Hn06ajHQH8KPAE\n2oDR3UPmblYGkB4H3DH19XcAj19l/53DfobPnx9u3w/cN3w/SZIkSZIkHSTbN7j/FuAi2rpF36BN\nPfv2TGbf8CFJkiRJkqQiNho0AnjX8AHw67Qrhu6mTUu7izb17EvD/XcCx0997ROG/J3D7dn9k695\nIvCFoc+RwD2zJZ7ylKfsu/322+eoK0mSJEmSpDl9Cjh5tTs2mp4G8Njh8xOBnwDeC3wQOGvYfxbw\ngeH2B2nrFR0GPBk4gbYA9l3A12hrF20Dfhr4g6mvmRzrFcBHVytx++23s2/fvlU/Xve61615X+/Z\nlB6Vsyk9KmdTevSWTelROZvSo7dsSo/K2ZQevWVTelTOpvSonE3p0Vs2pUflbEqP3rIpPdbLAs9Y\na0BoniuNfhf4HuBbtHc6u4/2bmlXAmcDe4EzhuxNw/6baOsTncPK1LVzgEuAh9PePe3qYf87gXcD\ntwJfoQ06jbJ3796y2ZQelbMpPSpnU3r0lk3pUTmb0qO3bEqPytmUHr1lU3pUzqb0qJxN6dFbNqVH\n5WxKj96yKT3Gdp6YZ9DoBavsuwd48Rr5Nwwfsz4JPH2V/X/LyqCTJEmSJEmSAhx6sAuMcOGFF164\n6h1HHXUUO3bsmOsgvWVTelTOpvSonE3p0Vs2pUflbEqP3rIpPSpnU3r0lk3pUTmb0qNyNqVHb9mU\nHpWzKT16y6b0WC/7+te/HuD1q923ba6jZ9g3zLWTJEmSJEnSAmzbtg3WGB+aZyHseEtLS2WzKT0q\nZ1N6VM6m9Ogtm9KjcjalR2/ZlB6Vsyk9esum9KicTelROZvSo7dsSo/K2ZQevWVTeoztPFFi0EiS\nJEmSJEmL5fQ0SZIkSZKkLar89DRJkiRJkiQtVolBo4Q5f85/7Deb0qNyNqVHb9mUHpWzKT16y6b0\nqJxN6dFbNqVH5WxKj8rZlB69ZVN6VM6m9Ogtm9JjbOeJEoNGkiRJkiRJWizXNJIkSZIkSdqiXNNI\nkiRJkiRJo5QYNEqY8+f8x36zKT0qZ1N69JZN6VE5m9Kjt2xKj8rZlB69ZVN6VM6m9KicTenRWzal\nR+VsSo/esik9xnaeKDFoJEmSJEmSpMVyTSNJkiRJkqQtyjWNJEmSJEmSNEqJQaOEOX/Of+w3m9Kj\ncjalR2/ZlB6Vsyk9esum9KicTenRWzalR+VsSo/K2ZQevWVTelTOpvToLZvSY2zniRKDRpIkSZIk\nSVos1zSSJEmSJEnaolzTSJIkSZIkSaOUGDRKmPPn/Md+syk9KmdTevSWTelROZvSo7dsSo/K2ZQe\nvWVTelTOpvSonE3p0Vs2pUflbEqP3rIpPcZ2nigxaCRJkiRJkqTFck0jSZIkSZKkLco1jSRJkiRJ\nkjRKiUGjhDl/zn/sN5vSo3I2pUdv2ZQelbMpPXrLpvSonE3p0Vs2pUflbEqPytmUHr1lU3pUzqb0\n6C2b0mNs54kSg0aSJEmSJElaLNc0kiRJkiRJ2qJc00iSJEmSJEmjlBg0Spjz5/zHfrMpPSpnU3r0\nlk3pUTmb0qO3bEqPytmUHr1lU3pUzqb0qJxN6dFbNqVH5WxKj96yKT3Gdp4oMWgkSZIkSZKkxZpn\nTaMLgJ8CvgPcCPwM8AjgCuBJwF7gDODeqfyrgW8D5wLXDPtPAS4BHgZcBZw37D8cuAx4FvAV4JXA\n51bp4ZpGkiRJkiRJC3QgaxrtAH6WNqDzdOBQ4EzgfOBa4ETgo8M2wEm0QZ+TgNOAi6e+8duBs4ET\nho/Thv1n0waLTgDeDFy00QN61KOOZtu2bWt+POpRR290CEmSJEmSJK1jo0GjrwHfAo4Atg+fvwC8\n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\n2ZQelbMpPSpnU3r0lk3pUTmb0qO3bEqP9bKsM3ts21p3rOKFwC/TFq4+GrgSeCKwl3Y10r1D7leA\nVwP3097mtEHFAAAgAElEQVR17Y+G/acAlwAPHwaNzh32Hw68G3gm7V3UzhyOudqgUSu9bdt6jwnX\nNJIkSZIkSdrYemsajRk0OtgcNJIkSZIkSVqgA1kIuxNL8yeX+sqm9KicTelROZvSo7dsSo/K2ZQe\nvWVTelTOpvToLZvSo3I2pUflbEqP3rIpPSpnU3r0lk3pMbbzRJFBI0mSJEmSJC2S09MkSZIkSZK2\nqC0wPU2SJEmSJEmLVGTQaGn+ZMD8wOrzH3vLpvSonE3p0Vs2pUflbEqP3rIpPSpnU3r0lk3pUTmb\n0qNyNqVHb9mUHpWzKT16y6b0GNt5osigkSRJkiRJkhbJNY0kSZIkSZK2KNc0kiRJkiRJ0ihFBo2W\n5k8GzA+sPv+xt2xKj8rZlB69ZVN6VM6m9Ogtm9KjcjalR2/ZlB6Vsyk9KmdTevSWTelROZvSo7ds\nSo+xnSeKDBpJkiRJkiRpkVzTSJIkSZIkaYtyTSNJkiRJkiSNUmTQaGn+ZMD8wOrzH3vLpvSonE3p\n0Vs2pUflbEqP3rIpPSpnU3r0lk3pUTmb0qNyNqVHb9mUHpWzKT16y6b0GNt5osigkSRJkiRJkhbJ\nNY0kSZIkSZK2KNc0kiRJkiRJ0ihFBo2W5k8GzA+sPv+xt2xKj8rZlB69ZVN6VM6m9Ogtm9Kjcjal\nR2/ZlB6Vsyk9KmdTevSWTelROZvSo7dsSo+xnSeKDBpJkiRJkiRpkVzTSJIkSZIkaYtyTSNJkiRJ\nkiSNUmTQaGn+ZMD8wOrzH3vLpvSonE3p0Vs2pUflbEqP3rIpPSpnU3r0lk3pUTmb0qNyNqVHb9mU\nHpWzKT16y6b0GNt5osigkSRJkiRJkhbJNY0kSZIkSZK2KNc0kiRJkiRJ0ihFBo2W5k8GzA+sPv+x\nt2xKj8rZlB69ZVN6VM6m9Ogtm9KjcjalR2/ZlB6Vsyk9KmdTevSWTelROZvSo7dsSo+xnSeKDBpJ\nkiRJkiRpkVzTSJIkSZIkaYtyTSNJkiRJkiSNstGg0cOAjwPLwE3Abwz7jwauBT4LXAMcNfU1FwC3\nArcAp07tPwW4cbjvLVP7DweuGPZfBzxp/MNYmj8ZMD+w+vzH3rIpPSpnU3r0lk3pUTmb0qO3bEqP\nytmUHr1lU3pUzqb0qJxN6dFbNqVH5WxKj96yKT3Gdp7YaNDom8APAycDPzDc/iHgfNqg0YnAR4dt\ngJOAVw6fTwMuZuUSp7cDZwMnDB+nDfvPBr4y7HszcNF+PRJJkiRJkiQtzJg1jY4APgbsAt4PvBC4\nGziWdqnPU2lXGX2HlYGfq4ELgc8Bfww8bdh/JrAT+Lkh8zraFU3bgS8Cj1nl+7umkSRJkiRJ0gId\n6JpGh9Cmp90N7AE+AxwzbDN8Pma4/TjgjqmvvQN4/Cr77xz2M3z+/HD7fuA+2vQ3SZIkSZIkHSTz\nDBp9hzY97QnAC2hT1KbtY/3Lfh4CS/MnA+YHVp//2Fs2pUflbEqP3rIpPSpnU3r0lk3pUTmb0qO3\nbEqPytmUHpWzKT16y6b0qJxN6dFbNqXH2M4T20dk7wP+kLag9WRa2l3AccCXhsydwPFTX/ME2hVG\ndw63Z/dPvuaJwBeGPkcC96xWYNeuXezYsWPY2k0by9o5bC8Nn9v25Aeyc+cDtyfWun96e3l5ed37\np7eXl5c3PN5Dsd3b40vpW/3xHey+1R+fz/+++1Z/fJvRt/rjS+hb/fFtVt/qjy+hb/XHl9C3+uPb\nrL7VH19C3+qPbyv9vrl7926Wl5enxlfWttGaRt9LmzJ2L/Bw4I+A1wMvpS1efRFtEeyjhs8nAe8F\nnkObdvYR4PtoVyJ9HDgXuJ42+PRW2npG5wBPB36ettbRy4fPs1zTSJIkSZIkaYHWW9NooyuNjgMu\npU1jOwR4N+3d0m4ArqS989le4Iwhf9Ow/ybaYNM5rIzunANcQht8uoo2YATwzuG4t9IGolYbMJIk\nSZIkSdJD6JAN7r8ReBZtHtgPAL857L8HeDFwInAq7UqkiTfQri56Ku3KpIlP0q4o+j7aFUcTf0sb\ndDoBeB5tEGqkpfmTM5dxpWdTelTOpvSonE3p0Vs2pUflbEqP3rIpPSpnU3r0lk3pUTmb0qNyNqVH\nb9mUHpWzKT16y6b0GNt5YqNBI0mSJEmSJG1BG61plMQ1jSRJkiRJkhZovTWNvNJIkiRJkiRJD1Jk\n0Ghp/mTA/MDq8x97y6b0qJxN6dFbNqVH5WxKj96yKT0qZ1N69JZN6VE5m9KjcjalR2/ZlB6Vsyk9\nesum9BjbeaLIoJEkSZIkSZIWyTWNJEmSJEmStijXNJIkSZIkSdIoRQaNluZPBswPrD7/sbdsSo/K\n2ZQevWVTelTOpvToLZvSo3I2pUdv2ZQelbMpPSpnU3r0lk3pUTmb0qO3bEqPsZ0nigwaSZIkSZIk\naZFc00iSJEmSJGmLck0jSZIkSZIkjVJk0Ghp/mTA/MDq8x97y6b0qJxN6dFbNqVH5WxKj96yKT0q\nZ1N69JZN6VE5m9KjcjalR2/ZlB6Vsyk9esum9BjbeaLIoJEkSZIkSZIWyTWNJEmSJEmStijXNJIk\nSZIkSdIoRQaNluZPBswPrD7/sbdsSo/K2ZQevWVTelTOpvToLZvSo3I2pUdv2ZQelbMpPSpnU3r0\nlk3pUTmb0qO3bEqPsZ0nigwaSZIkSZIkaZFc00iSJEmSJGmLck0jSZIkSZIkjVJk0Ghp/mTA/MDq\n8x97y6b0qJxN6dFbNqVH5WxKj96yKT0qZ1N69JZN6VE5m9KjcjalR2/ZlB6Vsyk9esum9BjbeaLI\noJEkSZIkSZIWyTWNJEmSJEmStijXNJIkSZIkSdIoRQaNluZPBswPrD7/sbdsSo/K2ZQevWVTelTO\npvToLZvSo3I2pUdv2ZQelbMpPSpnU3r0lk3pUTmb0qO3bEqPsZ0nigwaSZIkSZIkaZFc00iSJEmS\nJGmLck0jSZIkSZIkjVJk0Ghp/mTA/MDq8x97y6b0qJxN6dFbNqVH5WxKj96yKT0qZ1N69JZN6VE5\nm9KjcjalR2/ZlB6Vsyk9esum9BjbeaLIoJEkSZIkSZIWaZ41jY4HLgMeS1tI6N8AbwWOBq4AngTs\nBc4A7h2+5gLg1cC3gXOBa4b9pwCXAA8DrgLOG/YfPnyPZwFfAV4JfG6mh2saSZIkSZIkLdCBrmn0\nLeAfA38XeB7wC8DTgPOBa4ETgY8O2wAn0QZ9TgJOAy6e+uZvB84GThg+Thv2n00bLDoBeDNw0ZyP\nTZIkSZIkSZtgnkGju4Dl4fZ/Bm4GHg+8DLh02H8p8PLh9unA5bTBpr3AbcBzgeOARwLXD7nLpr5m\n+ljvB1407mEszZ8MmB9Yff5jb9mUHpWzKT16y6b0qJxN6dFbNqVH5WxKj96yKT0qZ1N6VM6m9Ogt\nm9KjcjalR2/ZlB5jO0+MXdNoB/BM4OPAMcDdw/67h22AxwF3TH3NHbRBptn9dw77GT5/frh9P3Af\nbfqbJEmSJEmSDoLtI7LfTbsK6Dzg6zP37WP9RYYWYteuXezYsWPY2g2cDOwcPpaG/TuBlVG0nTsP\nbHtio/xk3zzH37lz56g+Y/O9Pb6D3bf640voW/3xbWbf6o/vYPet/vg2s2/1x5fQt/rj24y+1R9f\nSt/qjy+hb/XHtxl9qz++lL7VH99m9E18fLt372Z5eXlqfGVt8yyEDfBdwL8DPkwbrQG4BdhJm752\nHLAHeCoraxu9cfh8NfA62sLWe2jrIQG8CngB8PND5kLgOtpA1heBx8x0cCFsSZIkSZKkBTrQhbC3\nAe8EbmJlwAjgg8BZw+2zgA9M7T8TOAx4Mm1x6+tpg0tfo61vtA34aeAPVjnWK2gLa4+wNH9yZoQt\nPZvSo3I2pUflbEqP3rIpPSpnU3r0lk3pUTmb0qO3bEqPytmUHpWzKT16y6b0qJxN6dFbNqXH2M4T\n80xP+3vATwF/Adww7LuAdiXRlbR3PtsLnDHcd9Ow/yba+kTnsHJZ0DnAJcDDgatoVxhBG5R6N3Ar\n7V3UztyvRyNJkiRJkqSFmHd6WgKnp0mSJEmSJC3QgU5PkyRJkiRJ0hZTZNBoaf5kwPzA6vMfe8um\n9KicTenRWzalR+VsSo/esik9KmdTevSWTelROZvSo3I2pUdv2ZQelbMpPXrLpvQY23miyKCRJEmS\nJEmSFsk1jSRJkiRJkrYo1zSSJEmSJEnSKEUGjZbmTwbMD6w+/7G3bEqPytmUHr1lU3pUzqb06C2b\n0qNyNqVHb9mUHpWzKT0qZ1N69JZN6VE5m9Kjt2xKj7GdJ4oMGkmSJEmSJGmRXNNIkiRJkiRpi3JN\nI0mSJEmSJI1SZNBoaf5kwPzA6vMfe8um9KicTenRWzalR+VsSo/esik9KmdTevSWTelROZvSo3I2\npUdv2ZQelbMpPXrLpvQY23miyKCRJEmSJEmSFsk1jSRJkiRJkrYo1zSSJEmSJEnSKEUGjZbmTwbM\nD6w+/7G3bEqPytmUHr1lU3pUzqb06C2b0qNyNqVHb9mUHpWzKT0qZ1N69JZN6VE5m9Kjt2xKj7Gd\nJ4oMGkmSJEmSJGmRXNNIkiRJkiRpi3JNI0mSJEmSJI1SZNBoaf5kwPzA6vMfe8um9KicTenRWzal\nR+VsSo/esik9KmdTevSWTelROZvSo3I2pUdv2ZQelbMpPXrLpvQY23miyKCRJEmSJEmSFsk1jSRJ\nkiRJkrYo1zSSJEmSJEnSKEUGjZbmTwbMD6w+/7G3bEqPytmUHr1lU3pUzqb06C2b0qNyNqVHb9mU\nHpWzKT0qZ1N69JZN6VE5m9Kjt2xKj7GdJ4oMGkmSJEmSJGmRXNNIkiRJkiRpi3JNI0mSJEmSJI1S\nZNBoaf5kwPzA6vMfe8um9KicTenRWzalR+VsSo/esik9KmdTevSWTelROZvSo3I2pUdv2ZQelbMp\nPXrLpvQY23miyKCRJEmSJEmSFsk1jSRJkiRJkraoA13T6F3A3cCNU/uOBq4FPgtcAxw1dd8FwK3A\nLcCpU/tPGY5xK/CWqf2HA1cM+68DnjRHJ0mSJEmSJG2ieQaNfhs4bWbf+bRBoxOBjw7bACcBrxw+\nnwZczMpo1duBs4ETho/JMc8GvjLsezNw0fiHsTR/MmB+YPX5j71lU3pUzqb06C2b0qNyNqVHb9mU\nHpWzKT16y6b0qJxN6VE5m9Kjt2xKj8rZlB69ZVN6jO08Mc+g0f8HfHVm38uAS4fblwIvH26fDlwO\nfAvYC9wGPBc4DngkcP2Qu2zqa6aP9X7gRWMegCRJkiRJkhZv3jWNdgAfAp4+bH8VePTUMe4Ztt9G\nm2L2nuG+dwAfpg0gvRF4ybD/+cBrgB+jTVl7KfCF4b7bgOcMx5zmmkaSJEmSJEkLtN6aRtsXcPx9\nrD+CszC7du1ix44dw9Zu4GRg57C9NHxu25NLr3budNttt91222233Xbbbbfddtttt912G2D37t0s\nLy9Pja8cuB08cCHsW4Bjh9vHDdvQ1jY6fyp3NW162rHAzVP7X0Vb42iSed5wezvw5TU67JsA9sG+\nqY89M9sr2Vl79uxZ877EbEqPytmUHpWzKT16y6b0qJxN6dFbNqVH5WxKj96yKT0qZ1N6VM6m9Ogt\nm9KjcjalR2/ZlB7rZVnnQqBD1h4nWtcHgbOG22cBH5jafyZwGPBk2uLW1wN3AV+jDSBtA34a+INV\njvUK2sLakiRJkiRJOojmWdPocuCFwPcCdwP/nDbgcyXwRNp6RWcA9w75XwFeDdwPnAf80bD/FOAS\n4OHAVcC5w/7DgXcDz6S9i9qZwzFnDQNgrmkkSZIkSZK0COutaTTvQtgJHDSSJEmSJElaoPUGjfZ3\nelqYpfmTS31lU3pUzqb0qJxN6dFbNqVH5WxKj96yKT0qZ1N69JZN6VE5m9KjcjalR2/ZlB6Vsyk9\nesum9BjbeaLIoJEkSZIkSZIWyelpkiRJkiRJW9QWmJ4mSZIkSZKkRSoyaLS05j2PetTRbNu2bc2P\nRz3q6LWPGjKXMKFH5WxKj8rZlB69ZVN6VM6m9Ogtm9KjcjalR2/ZlB6Vsyk9KmdTevSWTelROZvS\no7dsSo+xnSeKDBqt7etf/yptKtvkY88Dttv9kiRJkiRJmlZ+TSPXP5IkSZIkSVqdaxpJkiRJkiRp\nlCKDRkubkk2ZS5jQo3I2pUflbEqP3rIpPSpnU3r0lk3pUTmb0qO3bEqPytmUHpWzKT16y6b0qJxN\n6dFbNqXH2M4TRQaNJEmSJEmStEiuaeSaRpIkSZIkaYtyTSNJkiRJkiSNUmTQaGlTsilzCRN6VM6m\n9KicTenRWzalR+VsSo/esik9KmdTevSWTelROZvSo3I2pUdv2ZQelbMpPXrLpvQY23miyKCRJEmS\nJEmSFsk1jVzTSJIkSZIkbVGuaSRJkiRJkqRRigwaLW1KNmUuYUKPytmUHpWzKT16y6b0qJxN6dFb\nNqVH5WxKj96yKT0qZ1N6VM6m9Ogtm9KjcjalR2/ZlB5jO08UGTSSJEmSJEnSIrmmkWsaSZIkSZKk\nLco1jSRJkiRJkjRKkUGjpU3JpswlTOhROZvSo3I2pUdv2ZQelbMpPXrLpvSonE3p0Vs2pUflbEqP\nytmUHr1lU3pUzqb06C2b0mNs54kig0aSJEmSJElaJNc0ck0jSZIkSZK0RbmmkSRJkiRJkkYpMmi0\ntCnZlLmECT0qZ1N6VM6m9Ogtm9KjcjalR2/ZlB6Vsyk9esum9KicTelROZvSo7dsSo/K2ZQevWVT\neoztPFFk0EiSJEmSJEmL5JpGrmkkSZIkSZK2KNc0kiRJkiRJ0ihJg0anAbcAtwKvHfelS5uSTZlL\nmNCjcjalR+VsSo/esik9KmdTevSWTelROZvSo7dsSo/K2ZQelbMpPXrLpvSonE3p0Vs2pcfYzhMp\ng0aHAv+KNnB0EvAq4Gnzf/nyiG81f3Z5+eBnU3pUzqb0qJxN6dFbNqVH5WxKj96yKT0qZ1N69JZN\n6VE5m9KjcjalR2/ZlB6Vsyk9esum9BjbeSJl0Og5wG3AXuBbwPuA0+f/8ntHfKv5s/fee/CzKT0q\nZ1N6VM6m9Ogtm9KjcjalR2/ZlB6Vsyk9esum9KicTelROZvSo7dsSo/K2ZQevWVTeoztPJEyaPR4\n4PNT23cM+yRJkiRJknQQpAwaHeDbl+3dlOzevQc/m9KjcjalR+VsSo/esik9KmdTevSWTelROZvS\no7dsSo/K2ZQelbMpPXrLpvSonE3p0Vs2pcfYzhOrvqXaQfA84ELamkYAFwDfAS6ayiwDz3hoa0mS\nJEmSJJX2KeDkg11iPduB24EdwGG0AaIRC2FLkiRJkiSpqr8P/CVtQewLDnIXSZIkSZIkSZIkSZIk\nSVX9zCr7nga8CPjumf2nrZL9IeCk4fZO4J8MXzuPy+bMPR/4ZeDUNe5/HnDkcPsI4NeAf0db2+nI\nmey5wPFzft/DgbOAFw/b/xD418AvAN+1Sv4pwP8JvAV4M/BzwKPm/F7SQ+mxm3Tc79mk42qF5046\nOHzu9ctz16/NOnfg+Xso+Nzrl+dOD/D5me1zadPdPgB8Dnj51H03zGR/A7gO+ATwpuH2PwP+PW3w\nZNqHgA8Onycf35jaP+36qds/S1ur6XXAf2D1KXg30dZ3Avi3wG7aYNaFwO/NZO8Dvgj8CXAO8JhV\njjfxXuCKoeO7gd8Hfhq4dPiYdh5wLfBPgT8FLgbeANwM/PA636NnW/HF5CjgjcAtwFeBe4bbbxzu\nm9eHV9l35HCc/xf4X2buu3hm+3jgHVPf97eBT9P+nM6el6NnPr6H9naIk+1p0wPDRwHvBG6kPReO\nmclexMrz59nAX9Gmyf4NbQB52g2058ZT2NgPAntoP4fjac+r+2ivM89cJf9I2kDxZ4CvAf8J+Diw\na5XsZp2/yucONu/8jTl3i/JQnbu1rJUbc/5Ws9br5phzt1l83Vzh6+aKyucOMl43K5876O+5l3Du\nIOP8VT53k8dU9blX/XUT4BDaRSn/M/ATwHPJeSO0TXXjOh9/O5P9NCtXGO0A/gz4pWF7dtBoMlhz\nBPB1Vq7qeTjwFzPZG4D30AZQXkj7g/LF4fYLV8lO/Bkrf9geMfSbdfPU7T+fue9Tqxz7ENpVS+8C\nvgxcTbui6JEz2RuHz9uBL7EyMLVt6r6JTwOHDrePAD423H4ibdBrWm8vJJDxYpLwQnIN8FrgWFZe\nPI4Dzh/um/asNT5OAe5a5di/RzsfP04bqHw/8LDhvtnn3keBX6QNot4yfP8nDvveP5P9DvDXMx/f\nGj7/1Ux2+vu8E/i/aK8D/5g2kDxt+rm4RPuZA5wIfHIm+9fA/007r58Yjvc4VvcJ2lptrwLuAH6S\n9rN+EW1AdtYHaVdMHg/8H8A/HzpcRhu4nbZZ56/yuYPNO39jzt2Y182EcwfjXjfHnL8xr5tjzp2v\nmysSnnu+bq7o7dxBxutm5XM3+716eO4lnDvIOH+Vzx3Ufu5Vf908lfY71dW0fyu/Y7h9O/DSNbqU\ncTftF74dq3x8YSb7mZnt7wb+iDbdanbwY3mN26ttH0o7SR9h5ZfPv16j71+w8gv27BNg9rgAvwu8\nerj92zzwD+QnZrKzxzsMOB14H+2X3mmfoU1RezRtUGzyP7kP58E/pxtZedIeTRvsmj7OtN5eSCDj\nxSThheSza3y/1e77Nu0fYKt9/NdVvn52gPNXaVfXfS/rPw/+Zp37oE3tvBr4gal9az33pr/Pp3jg\nqPpsv5tZmaZ53cx9s4Oqk+NuA14AvJ3253cP8L+t02GjxwYPHqCePPcOoV01OW2zzl/lczd97EWf\nvzHnbszrZsK5g/1/3dzo/I153Rxz7nzdXJHw3PN1c0Vv52762AfzdbPyuYP+nnsJ5w4yzl/lcwe1\nn3vVXzdvof27ddaTh/tKexdtXaDVXD6zvQc4eWbfd9F+EfzOzP6P066qgfZDnziKB1/xM/EE4Hdo\nawPNTo2b2MvKL9h/RfuHAbT/2Vztl5+jaNPF/mroNPml/N8Dz5jJzj6hpj1iZvuC4Zh/SfuDehNt\ntPHTwGtmsufR/vC/Y8hPBrEeO/SY1tsLCWS8mCS8kFxLO/fTV0wdS/vH7Edmsp+h/SNqNav92b+Z\nBz6PoP2v/WdoU0WnTf8cf33mvtVehI+nPe/eTFtna61zdwftH4C/THseTp+72Z/TL9J+Hj9Cmwr6\nFtpVg6+nXbE2bbXn3XbaVWm/PbP/etpI/hm0n9OPD/tfSHt+z/pTVl7fTqcNck88VOev8rmDzTt/\nY87dmNfNlHM35nVzzPnbn9fNaWudO183H+hgP/d83VzR27mDcefvE2zO62blcwcZz73ezh1knL+E\nc7dZv69A7edeyuvm9Pm7g8Wdv1tZfe3iw2hXIGlwPO0P9axttHWCpj1slRy0QYqnb/B9/gGrX863\nniNoo3xrOZI24PVsVn8MAH9n5Pfcwco0gqcAr+TBA1ET3w+8AnjqBsfs8YUEDv6LScJfBEfT1u+a\nTJH56nD7TTx4uslPsvafhZevsu83gZessv802gvYtH/Bg6dTApxAu/JuLafTHv/da9x/IW39sMnH\nZKricay+cP0P09b9uoH25+bDwP/Og19sr1in06zn0K6euBx4Eu058TXaQPSzV8k/g/ZL2720QdLJ\nc/wxtDXapi3q/P34zPYizt33sfG5u47x5+5YDuzcwfjzt4f5zt965+68meyY182H+tyt97yb93Xz\nQtp5m3yefu7NvhaOed0cc+7SXzdnzx30+9y7ktzXzdnn3mrn72Ye2tfNX+PAzt1qU3TgweduMu1z\n3nN3FWu/br5vnV6z1jp/n2Tc6+aB/J233u+vm3HuDvT3FVj/dfNAnnuLOHdj/86b59wt4nkH7fy9\neJX9a71uzr4xEiz+ubeo31kW8fvKWs+765nvNROyf9+c57k35u+8yevmgf5bAfbv77330mbLXMt8\nz70/Yf3n3gW0/yh7Le1NsP4h7ar2ZeBXRvSTDthmDTw8FC8ksDkDD738JQ7t3QVfzIN/fqetkV3t\nnQj//hq9x+T3N3sEK4O6a2VfPOK4B/qzWCs7b4f1eqyW/yHg7w63f5j13/FxzLtDPhTZH6Wt67Ve\ndvLY5jnuvNn96Tx77NV+QR3TY8zr5mrmfbfOzcrO8w+gMcee93VzzHEX9bq52i/Q0zZ6R9T9zW7m\nsZ9Pe+5txnE3Mzvv+gvrHfu5rKxZ+Qja7w9/SHvuHTmTHfNututlZ9cpO5Dsb9L+LB9oh9V+Dms9\nto2OvVGPeX/Gj9jguGPeMfi8gOxs3+nfVxZ97PWMfXxPHNFh3uzkHZwnv9f/FGu/g/N67/Z82DrH\nnid/INn/FfjjBXSe/Vms927WY975erXjXgz8ozmz6/2MoV1s8BrgrbT/OPp5Vn+tmGTnfQfuzc6+\nFfh/aH9e58mOOe7k57Deu4sfyOPb6Gc8fT7WO+5JtMGjtw0f57PyO/AoW2L1bB0UP8ODr5pZy6tp\nUw8PRvYI2pPvRjav85jjblZ2tu+5tL8gbqatzXUeK+s03cADF4sdk93MY1fOjs3/Bu0f24fS/nfp\nBbRfzF9CWwfsN80+KJvUY9a7ae9oOetDwD4e+Hf1j9B+ed0HvOwhyK7mCNqAzSsOsPNqFvGzGHPc\n1VxG+0fCrOtpA1LQ3hH1F2jvRnoq7R+7v7Gf2c08duXs2PxNtCmW99PeofYbtP9cevGw/yfMPiib\n0uM+4L/QplRcTrvq8cusbpK9nfY/9+nZ6fyYx7dZP4tFd3gv7e/GI2iD899NW7t0Mhhy1n5mN/PY\nVbIvov2deSA/4/Nos2o+RvsPv2Xaf3b9BO3du/eskf2faL+73ku7yuhgZMf0nWQXcdxFPL5FdJa6\nsNY6T6nZlB4PVXb23QU/ydrvLjjmnQjH5s3uX37MOz6azerxIdriyx+a+vjG1P5pNzDu3TrXyu48\ngMJaphYAAALKSURBVOwiO88ee7N+FmOOO7bDxEbviDomu5nHrpwdmx/zDrVms3rcwPzvGNxbNqXH\nZmUnS0XM8w7OY7KbeWyzK8a8q7bZrB6LepdzYOUPirQ/1lozCB78lvQJ2Y3yj53ZXlSPMcfdrA6z\n2W3Afx5u76X9o+v9tKkcs1cgzmZ3rpMdmze7f/n/Rvvf2ftp/4N437D/v/Lghf7NZvV4AitvRvAd\n2rl9Nu0dFWc9m/a/Sr9Ku2z5BuCbrPyS8FBkN7NzwnHHZA+lTSHcNtye/M/6N2jnfn+zm3nsytmx\n+c+wctXtp2jv1vcJ2nqL/83sqtmkHt+hvcPkNbRpNJN3SPyXtDVIe86m9NiM7CG0KVFH0P4j5Ujg\nK7T1ZGfXLx2T3cxjm12xjzbF7dtD5hHD/r/hwVPfzGb1uJL2LuM7aUsK7KMtsXLWcN+80+WlA3Y3\nbcrMjlU+vhCYTemRkN3D/O8uOCa7mceunB2bH/OOj2azehxKW2D/I6xMOfzrVbpOm+fdOjczu1md\nE447JruX+d8RdUx2M49dOTs2P+Ydas1m9Vjt6tyJR8xs95ZN6bFZ2THv4Dwmu5nHNrviPOZ/V22z\nWT3GvFuvtKnexcq7zsy6PDCb0iMhO+bdBcdkN/PYlbNj82Pe8dFsXg8YN7gzMebdOjcju1mdE467\nPx0mjmD9d0Td3+xmHrtydqP8kWz8DrVms3qMecfg3rIpPTbz8e1g/ndwHpPdzGObXTHvu2qbzeox\n5t16JUlSsDGDOyk2q3PCcXs8H5IkSdMO9N16JUmSJEmStMX8zMEuIEmSJEmSpDxjp+H77mmSJEmS\nJElFjH2H8XU5aCRJkiRJklTDY4HTaGsZzfqPYw/moJEkSZIkSVINfwh8N3DDKvd97CHuIkmSJEmS\nJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJElz+v8BnxTmfWvZvLMAAAAASUVORK5C\nYII=\n", "text": [ "" ] } ], "prompt_number": 61 }, { "cell_type": "code", "collapsed": false, "input": [ "plt.figure(figsize = (20,6))\n", "indices = nenas.T.xs('nombre', level = 'campo') == 'LUCIA'\n", "#nenas.T.xs('numero',level = 'campo')[indices].sum(axis = 1).plot(kind = 'bar', color = 'k')\n", "nenas.T.xs('numero',level = 'campo')[indices].sum(axis = 1).plot(color = 'k')\n", "print(nenas.T.xs('numero',level = 'campo')[indices].sum().sum())\n", "indices = nenas.T.xs('nombre', level = 'campo') == 'MARIA'\n", "#nenas.T.xs('numero',level = 'campo')[indices].sum(axis = 1).plot(kind = 'bar', color = 'y', alpha = 0.75)\n", "nenas.T.xs('numero',level = 'campo')[indices].sum(axis = 1).plot(color = 'y')\n", "print(nenas.T.xs('numero',level = 'campo')[indices].sum().sum())\n", "indices = nenas.T.xs('nombre', level = 'campo') == 'PAULA'\n", "#nenas.T.xs('numero',level = 'campo')[indices].sum(axis = 1).plot(kind = 'bar', color = 'y', alpha = 0.75)\n", "nenas.T.xs('numero',level = 'campo')[indices].sum(axis = 1).plot(color = 'b')\n", "print(nenas.T.xs('numero',level = 'campo')[indices].sum().sum())" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "88899.0\n", "77750.0" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n", "69759.0" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n" ] }, { "metadata": {}, "output_type": "display_data", "png": "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\nm9TUVNq3b0+rVq347rvvGDFiBCtXruSJJ56gdevWuz85loq94vhzLzY2lkGDBvH+++8zduxYLrro\nIlauXBl0WNIRs8AkSZIk5ZP169czfvx4zjvvPBo1asS8efO45557yMzMZMyYMZx99tnExMQEHaak\nQqRJkybMnj2bs88+224mRbRI+cjEGUySJEkqlDZv3syrr77KlClT+PDDD7ngggtISkrikksuoUyZ\nMkGHJymCLFq0iOTkZKpWrcozzzzjbCYdc85gkiRJkgK0bds2pk+fzrXXXktCQgKTJ0/m2muvZdWq\nVUybNo0//vGPFpckHbYmTZrwySefcNZZZ9GyZUvGjx9vN5MihgUmSftVHPfCS4WF+ScF40C5t2vX\nLt566y2Sk5OJj48nNTWV8847jxUrVvDGG29w/fXXc9xxxxVcsFIR4s+935QoUYK77rqL999/nzFj\nxnDxxRezatWqoMOSDsoCkyRJkrQfoVCIjz76iNtuu434+Hjuu+8+EhMTWbRoEe+//z7dunWjWrVq\nQYcpqQja3c105plnctpppzFhwgS7mVSoOYNJkiRJ2kM4HGb+/PlMnTqVl156icqVK5OUlERSUhJ1\n69YNOjxJxdDChQtJTk6mevXqjBs3jlq1agUdkooIZzBJkiRJ+Wz58uXce++9NGjQgKSkJMqUKcOb\nb77JggULGDx4sMUlSYFp2rQps2fP5owzzrCbSYWWBSZJ++VeeCk45p9UcLZt28Y999xDu3bt+Oqr\nr3jxxRdZtmwZDz74II0bNw46PKlY8OfewZUoUYK7776b9957j9GjR3PJJZfwww8/BB2W9CsLTJIk\nSSq20tPTadasGUuWLOGLL76gR48etGrVaveWAUkqdJo1a8ann35K+/btadGiBWlpaXYzqVCIlJ+c\nzmCSJElSvlm3bh133HEH7777LiNHjuSKK64IOiRJOmwLFiwgOTmZmjVrMm7cOE444YSgQ1KEcQaT\nJEmSdATC4TCTJ0+mSZMmVKhQgcWLF1tckhSxdncztWvXjtNOO42JEyfazaTAWGCStF/uhZeCY/5J\n+e/bb7/loosu4rHHHuNf//oXI0aMoEKFCns9xtyTgmHuHbkSJUpwzz338O6775Kamspll11GRkZG\n0GGpGLLAJEmSpCJt586dPPbYY7Ru3ZrzzjuPefPm0bp166DDkqR81axZM+bMmUObNm1o0aKF3Uwq\ncM5gkiRJUpE1Z84cbr75ZmrWrMnTTz9N3bp1gw5Jko65L7/8kuTkZOLj4xk3bhwJCQlBh6RCyhlM\nkiRJ0gFs2rSJ3r1706lTJ+68807efPNNi0uSio3mzZvv1c00adIku5l0zFlgkrRf7oWXgmP+SUfu\n1VdfpXHjxmzatInFixfz5z//efcntAdl7knBMPfyX4kSJbj33nt55513GDFiBJdffrmzmXRMWWCS\nJElSkZCRkcEf//hH+vfvz7PPPktaWhpVq1YNOixJCtTubqZWrVrRokULnn32WbuZdEw4g0mSJEkR\nLRQKMWbMGO677z66d+/O4MGDKV26dNBhSVKh88UXX5CcnMwJJ5zAuHHjiI+PDzokBcwZTJIkSRKw\naNEi/vCHP/Diiy/ywQcf8MADD1hckqT9SExMZM6cOZx++ukkJibazaR8ZYFJ0n65F14KjvknHdjW\nrVu56667OOecc7jxxhv58MMPOfXUU4/6vOaeFAxzr+CULFmSIUOG8PbbbzN8+HA6depEZmZm0GGp\nCLDAJEmSpIjy3nvv0axZM5YtW8aCBQu45ZZbiI7211pJOhy7u5latmxJYmIizz33nN1MOirOYJIk\nSVJE+PHHH+nXrx/p6emMHj2ayy67LOiQJKlI+Pzzz0lOTubEE09k7NixzmYqRpzBJEmSpGIjHA7z\n/PPP06RJE6pUqcLixYstLklSPmrRogVz587ltNNOIzExkeeff95uJh02C0yS9su98FJwzD8p1/Ll\ny+nYsSNPPPEEr7/+OsOHD6d8+fLH7PXMPSkY5l7wSpYsyf33389bb73F448/zhVXXEFWVlbQYSmC\nWGCSJElSobNz506GDh1K27Ztufjii5k7dy6nn3560GFJUpG3u5spMTGR5s2b282kQ+YMJkmSJBUq\ns2fPplu3biQkJPDUU09Rp06doEOSpGLps88+Izk5mdq1azN27Fji4uKCDkn5zBlMkiRJKnI2btxI\nz549ueqqqxg8eDAzZsywuCRJATrttNOYN28eiYmJJCYm8sILL9jNpP2ywCRpv9wLLwXH/FNxM336\ndE499VS2b9/OokWLSEpK2v2paoEy96RgmHuFV8mSJXnggQeYOXMmjz32GJ07d3Y2k/bpaApMvYGF\nwKK8+wBVgHeAb4C3gUp7PH4QsAxYClywx/GWeedZBow4ingkSZIUYX744Qc6d+7MoEGDePHFF3nm\n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\n6A1g+X2O5Xf/q5jZS9sxAdMdg7NMERERERERERERERERERERERERERERERERERERERERERERERER\nEREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREZEQ8v8BVzRc\nxjokvLEAAAAASUVORK5CYII=\n", "text": [ "" ] } ], "prompt_number": 62 }, { "cell_type": "code", "collapsed": false, "input": [ "nenes.T.xs('nombre', level = 'campo')" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
1234567891011121314151617181920
a\u00f1o
2012 DANIEL HUGO ALEJANDRO PABLO ALVARO ADRIAN DAVID DIEGO MARIO JAVIER MARCOS MANUEL SERGIO NICOLAS IKER LUCAS IVAN CARLOS MIGUEL JORGE...
2011 ALEJANDRO DANIEL PABLO HUGO ALVARO ADRIAN DAVID DIEGO JAVIER MARIO SERGIO MARCOS MANUEL IKER NICOLAS JORGE IVAN CARLOS MIGUEL LUCAS...
2010 DANIEL ALEJANDRO PABLO HUGO ALVARO ADRIAN DAVID JAVIER DIEGO MARIO MARCOS SERGIO IKER IVAN MANUEL JORGE AITOR MIGUEL CARLOS SAMUEL...
2009 DANIEL ALEJANDRO PABLO HUGO ALVARO ADRIAN DAVID JAVIER SERGIO DIEGO IVAN MARIO MARCOS IKER MANUEL CARLOS JORGE MIGUEL SAMUEL LUCAS...
2008 DANIEL ALEJANDRO PABLO DAVID ADRIAN HUGO ALVARO JAVIER DIEGO SERGIO MARCOS IVAN IKER MANUEL MARIO JORGE CARLOS MIGUEL RUBEN ANTONIO...
2007 DANIEL ALEJANDRO PABLO DAVID ADRIAN ALVARO HUGO JAVIER DIEGO SERGIO MARCOS JORGE IVAN CARLOS MANUEL MARIO MIGUEL IKER RUBEN ANTONIO...
2006 ALEJANDRO DANIEL PABLO DAVID ADRIAN ALVARO JAVIER SERGIO HUGO DIEGO CARLOS MARCOS MARIO IVAN MANUEL MIGUEL JORGE RUBEN IKER RAUL...
2005 ALEJANDRO DANIEL PABLO DAVID ADRIAN JAVIER ALVARO SERGIO CARLOS MARCOS IVAN HUGO DIEGO JORGE MIGUEL MANUEL MARIO RAUL ANTONIO RUBEN...
2004 ALEJANDRO DAVID DANIEL PABLO ADRIAN ALVARO JAVIER SERGIO CARLOS MARCOS IVAN HUGO MARIO JORGE DIEGO MIGUEL MANUEL RAUL RUBEN ANTONIO...
2003 ALEJANDRO DANIEL PABLO DAVID JAVIER ADRIAN ALVARO SERGIO CARLOS HUGO MARIO JORGE DIEGO IVAN RAUL MANUEL MIGUEL ANTONIO RUBEN JUAN...
2002 ALEJANDRO PABLO DANIEL DAVID ADRIAN JAVIER ALVARO SERGIO CARLOS MARIO JORGE RAUL MANUEL DIEGO MIGUEL IVAN ANTONIO JUAN RUBEN VICTOR...
\n", "

11 rows \u00d7 100 columns

\n", "
" ], "metadata": {}, "output_type": "pyout", "prompt_number": 63, "text": [ " 1 2 3 4 5 6 7 8 \\\n", "a\u00f1o \n", "2012 DANIEL HUGO ALEJANDRO PABLO ALVARO ADRIAN DAVID DIEGO \n", "2011 ALEJANDRO DANIEL PABLO HUGO ALVARO ADRIAN DAVID DIEGO \n", "2010 DANIEL ALEJANDRO PABLO HUGO ALVARO ADRIAN DAVID JAVIER \n", "2009 DANIEL ALEJANDRO PABLO HUGO ALVARO ADRIAN DAVID JAVIER \n", "2008 DANIEL ALEJANDRO PABLO DAVID ADRIAN HUGO ALVARO JAVIER \n", "2007 DANIEL ALEJANDRO PABLO DAVID ADRIAN ALVARO HUGO JAVIER \n", "2006 ALEJANDRO DANIEL PABLO DAVID ADRIAN ALVARO JAVIER SERGIO \n", "2005 ALEJANDRO DANIEL PABLO DAVID ADRIAN JAVIER ALVARO SERGIO \n", "2004 ALEJANDRO DAVID DANIEL PABLO ADRIAN ALVARO JAVIER SERGIO \n", "2003 ALEJANDRO DANIEL PABLO DAVID JAVIER ADRIAN ALVARO SERGIO \n", "2002 ALEJANDRO PABLO DANIEL DAVID ADRIAN JAVIER ALVARO SERGIO \n", "\n", " 9 10 11 12 13 14 15 16 \\\n", "a\u00f1o \n", "2012 MARIO JAVIER MARCOS MANUEL SERGIO NICOLAS IKER LUCAS \n", "2011 JAVIER MARIO SERGIO MARCOS MANUEL IKER NICOLAS JORGE \n", "2010 DIEGO MARIO MARCOS SERGIO IKER IVAN MANUEL JORGE \n", "2009 SERGIO DIEGO IVAN MARIO MARCOS IKER MANUEL CARLOS \n", "2008 DIEGO SERGIO MARCOS IVAN IKER MANUEL MARIO JORGE \n", "2007 DIEGO SERGIO MARCOS JORGE IVAN CARLOS MANUEL MARIO \n", "2006 HUGO DIEGO CARLOS MARCOS MARIO IVAN MANUEL MIGUEL \n", "2005 CARLOS MARCOS IVAN HUGO DIEGO JORGE MIGUEL MANUEL \n", "2004 CARLOS MARCOS IVAN HUGO MARIO JORGE DIEGO MIGUEL \n", "2003 CARLOS HUGO MARIO JORGE DIEGO IVAN RAUL MANUEL \n", "2002 CARLOS MARIO JORGE RAUL MANUEL DIEGO MIGUEL IVAN \n", "\n", " 17 18 19 20 \n", "a\u00f1o \n", "2012 IVAN CARLOS MIGUEL JORGE ... \n", "2011 IVAN CARLOS MIGUEL LUCAS ... \n", "2010 AITOR MIGUEL CARLOS SAMUEL ... \n", "2009 JORGE MIGUEL SAMUEL LUCAS ... \n", "2008 CARLOS MIGUEL RUBEN ANTONIO ... \n", "2007 MIGUEL IKER RUBEN ANTONIO ... \n", "2006 JORGE RUBEN IKER RAUL ... \n", "2005 MARIO RAUL ANTONIO RUBEN ... \n", "2004 MANUEL RAUL RUBEN ANTONIO ... \n", "2003 MIGUEL ANTONIO RUBEN JUAN ... \n", "2002 ANTONIO JUAN RUBEN VICTOR ... \n", "\n", "[11 rows x 100 columns]" ] } ], "prompt_number": 63 }, { "cell_type": "code", "collapsed": false, "input": [ "plt.figure(figsize = (20,6))\n", "indices = nenes.T.xs('nombre', level = 'campo') == 'DANIEL'\n", "nenes.T.xs('numero',level = 'campo')[indices].sum(axis = 1).plot(color = 'k')\n", "print(nenes.T.xs('numero',level = 'campo')[indices].sum().sum())\n", "indices = nenes.T.xs('nombre', level = 'campo') == 'ALEJANDRO'\n", "nenes.T.xs('numero',level = 'campo')[indices].sum(axis = 1).plot(color = 'y', alpha = 0.5)\n", "print(nenes.T.xs('numero',level = 'campo')[indices].sum().sum())\n", "indices = nenes.T.xs('nombre', level = 'campo') == 'PABLO'\n", "nenes.T.xs('numero',level = 'campo')[indices].sum(axis = 1).plot(color = 'b', alpha = 0.5)\n", "print(nenes.T.xs('numero',level = 'campo')[indices].sum().sum())\n", "indices = nenes.T.xs('nombre', level = 'campo') == 'HUGO'\n", "nenes.T.xs('numero',level = 'campo')[indices].sum(axis = 1).plot(color = 'g', alpha = 0.5)\n", "print(nenes.T.xs('numero',level = 'campo')[indices].sum().sum())" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "68603.0\n", "74439.0\n", "63519.0" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n", "44830.0" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n" ] }, { "metadata": {}, "output_type": "display_data", "png": "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\n", "text": [ "" ] } ], "prompt_number": 64 }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [] } ], "metadata": {} } ] }