{ "metadata": { "name": "", "signature": "sha256:094970f3f7600aed9df619d84bc2f95367efd522cc3e4420116ffa9ce2e167c1" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "PyLadies Mola" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![pyladies](http://static.ow.ly/photos/normal/7qKyP.jpg)" ] }, { "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.4.1 |Continuum Analytics, Inc.| (default, Jun 11 2014, 17:29:32) [MSC v.1600 32 bit (Intel)]\n", "Versi\u00f3n de Pandas: 0.14.1\n", "Versi\u00f3n de Numpy: 1.9.0\n", "Versi\u00f3n de Matplotlib: 1.4.0\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.display import HTML\n", "HTML(\"\")" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "" ], "metadata": {}, "output_type": "pyout", "prompt_number": 3, "text": [ "" ] } ], "prompt_number": 3 }, { "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](http://pandas.pydata.org/pandas-docs/version/0.15.0/cookbook.html#timeseries)" ] }, { "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": 4 }, { "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.391483\n", "b -0.791497\n", "c -0.393253\n", "d 1.541392\n", "e -0.427196\n", "f 0.075259\n", "g -0.473327\n", "h -0.341977\n", "i 0.955735\n", "j 0.087599\n", "dtype: float64\n", "\n", "\n", "Se comporta como un numpy array:\n", "================================\n", ">>> serie.max()\n", "1.541392030043323\n", ">>> serie.sum()\n", "-0.1587485293714984\n", ">>> serie.abs()\n", "a 0.391483\n", "b 0.791497\n", "c 0.393253\n", "d 1.541392\n", "e 0.427196\n", "f 0.075259\n", "g 0.473327\n", "h 0.341977\n", "i 0.955735\n", "j 0.087599\n", "dtype: float64\n", ">>> serie[serie > 0]\n", "d 1.541392\n", "f 0.075259\n", "i 0.955735\n", "j 0.087599\n", "dtype: float64\n", "\n", "\n", "Se comporta como un diccionario:\n", "================================\n", ">>> serie['a']\n", "-0.39148310784072204\n", ">>> 'a' in serie\n", "True\n", ">>> 'z' in serie\n", "False\n" ] } ], "prompt_number": 5 }, { "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](http://pandas.pydata.org/pandas-docs/version/0.15.0/cookbook.html#dataframes)" ] }, { "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", "\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", "\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](http://pandas.pydata.org/pandas-docs/version/0.15.0/cookbook.html#panels)" ] }, { "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)](http://pandas.pydata.org/pandas-docs/version/0.15.0/cookbook.html#data-in-out)" ] }, { "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": 9 }, { "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": 10 }, { "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" ] } ], "prompt_number": 11 }, { "cell_type": "code", "collapsed": false, "input": [ "data.index" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 12, "text": [ "\n", "[1990-10-01 00:00:00, ..., 1990-10-03 18:00:00]\n", "Length: 11, Freq: None, Timezone: None" ] } ], "prompt_number": 12 }, { "cell_type": "code", "collapsed": false, "input": [ "data.columns" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 13, "text": [ "Index(['rec1', 'rec2', 'rec3', 'rec4'], dtype='object')" ] } ], "prompt_number": 13 }, { "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", "
" ], "metadata": {}, "output_type": "pyout", "prompt_number": 14, "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" ] } ], "prompt_number": 14 }, { "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": 15 }, { "cell_type": "code", "collapsed": false, "input": [ "%load dummy.csv" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 16 }, { "cell_type": "code", "collapsed": true, "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" ], "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,...](http://pandas.pydata.org/pandas-docs/version/0.15.0/cookbook.html#selection)" ] }, { "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.116147\n", "segundo -0.031326\n", "tercero -2.036800\n", "cuarto -0.432879\n", "quinto -0.944108\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.116147\n", "segundo -0.031326\n", "tercero -2.036800\n", "cuarto -0.432879\n", "quinto -0.944108\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.116147 1.429746 -0.937557 -0.316761\n", "segundo -0.031326 -0.036688 -1.214472 -0.518240\n", "tercero -2.036800 1.403272 1.338877 -0.311148\n", "cuarto -0.432879 -0.163595 -1.475231 -0.911488\n", "quinto -0.944108 -1.066021 0.007308 -0.510045\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.116147 1.429746 -0.937557 -0.316761\n", "segundo -0.031326 -0.036688 -1.214472 -0.518240\n", "tercero -2.036800 1.403272 1.338877 -0.311148\n", "cuarto -0.432879 -0.163595 -1.475231 -0.911488\n", "quinto -0.944108 -1.066021 0.007308 -0.510045\n", " velocidad temperatura presion\n", "primero 0.116147 1.429746 -0.937557\n", "segundo -0.031326 -0.036688 -1.214472\n", "tercero -2.036800 1.403272 1.338877\n", "cuarto -0.432879 -0.163595 -1.475231\n", "quinto -0.944108 -1.066021 0.007308\n", "primero -0.316761\n", "segundo -0.518240\n", "tercero -0.311148\n", "cuarto -0.911488\n", "quinto -0.510045\n", "Name: velocidad_maxima, dtype: float64\n", " velocidad velocidad_maxima temperatura presion\n", "primero 0.116147 -0.316761 1.429746 -0.937557\n", "segundo -0.031326 -0.518240 -0.036688 -1.214472\n", "tercero -2.036800 -0.311148 1.403272 1.338877\n", "cuarto -0.432879 -0.911488 -0.163595 -1.475231\n", "quinto -0.944108 -0.510045 -1.066021 0.007308\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.116147 -0.316761 1.429746 -0.937557\n", "segundo -0.031326 -0.518240 -0.036688 -1.214472\n", "tercero -2.036800 -0.311148 1.403272 1.338877\n", "cuarto -0.432879 -0.911488 -0.163595 -1.475231\n", "quinto -0.944108 -0.510045 -1.066021 0.007308\n", " velocidad temperatura presion\n", "primero 0.116147 1.429746 -0.937557\n", "segundo -0.031326 -0.036688 -1.214472\n", "tercero -2.036800 1.403272 1.338877\n", "cuarto -0.432879 -0.163595 -1.475231\n", "quinto -0.944108 -1.066021 0.007308\n", "primero -0.316761\n", "segundo -0.518240\n", "tercero -0.311148\n", "cuarto -0.911488\n", "quinto -0.510045\n", "Name: velocidad_maxima, dtype: float64\n", " velocidad temperatura presion velocidad_maxima\n", "primero 0.116147 1.429746 -0.937557 -0.316761\n", "segundo -0.031326 -0.036688 -1.214472 -0.518240\n", "tercero -2.036800 1.403272 1.338877 -0.311148\n", "cuarto -0.432879 -0.163595 -1.475231 -0.911488\n", "quinto -0.944108 -1.066021 0.007308 -0.510045\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](http://pandas.pydata.org/pandas-docs/version/0.15.0/cookbook.html#merge)" ] }, { "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]\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]\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]\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]\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]\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]\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", "\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]\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]\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 = 0, skiprows = 1)\n", "nenes = pd.read_excel('nombres_recien_nacidos.xlsx', 'Ni\u00f1os', header = 0, skiprows = 1)" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 54 }, { "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.4...nombre.6numero.6nombre.7numero.7nombre.8numero.8nombre.9numero.9nombre.10numero.10
0 LUCIA 6363 LUCIA 6143 LUCIA 6624 LUCIA 6847 LUCIA 8013... LUCIA 9454 LUCIA 10146 LUCIA 10370 LUCIA 9035 MARIA 8838
1 MARIA 5823 PAULA 5462 PAULA 5859 PAULA 6549 MARIA 6883... MARIA 7702 MARIA 7784 MARIA 7865 MARIA 8709 LUCIA 7712
2 PAULA 5375 MARIA 5339 MARIA 5767 MARIA 6113 PAULA 6806... PAULA 6516 PAULA 6684 PAULA 7147 PAULA 7003 PAULA 5956
3 DANIELA 4748 SARA 4345 DANIELA 4680 SARA 4417 SARA 4730... LAURA 5144 LAURA 5276 LAURA 5638 LAURA 5451 LAURA 5544
4 SARA 4456 DANIELA 4270 SARA 4662 DANIELA 4279 CARLA 4271... CLAUDIA 4756 MARTA 4592 MARTA 4583 MARTA 4608 MARTA 4644
\n", "

5 rows \u00d7 22 columns

\n", "
" ], "metadata": {}, "output_type": "pyout", "prompt_number": 55, "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.6 numero.6 nombre.7 numero.7 nombre.8 \\\n", "0 LUCIA 8013 ... LUCIA 9454 LUCIA 10146 LUCIA \n", "1 MARIA 6883 ... MARIA 7702 MARIA 7784 MARIA \n", "2 PAULA 6806 ... PAULA 6516 PAULA 6684 PAULA \n", "3 SARA 4730 ... LAURA 5144 LAURA 5276 LAURA \n", "4 CARLA 4271 ... CLAUDIA 4756 MARTA 4592 MARTA \n", "\n", " numero.8 nombre.9 numero.9 nombre.10 numero.10 \n", "0 10370 LUCIA 9035 MARIA 8838 \n", "1 7865 MARIA 8709 LUCIA 7712 \n", "2 7147 PAULA 7003 PAULA 5956 \n", "3 5638 LAURA 5451 LAURA 5544 \n", "4 4583 MARTA 4608 MARTA 4644 \n", "\n", "[5 rows x 22 columns]" ] } ], "prompt_number": 55 }, { "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\u00f1o20122011201020092008...20062005200420032002
camponombrenumeronombrenumeronombrenumeronombrenumeronombrenumero...nombrenumeronombrenumeronombrenumeronombrenumeronombrenumero
96 YERAY 517 GAEL 439 JUANJOSE 442 YERAY 458 JUANANTONIO 467... BRUNO 478 ADAM 427 MIKEL 431 IZAN 397 JOSEMIGUEL 389
97 GAEL 501 YERAY 439 JON 436 JOSEMARIA 447 AIMAR 464... SAUL 477 JON 419 MATEO 428 GUILLEM 385 ANDER 382
98 JON 493 JON 431 NIL 425 SERGI 447 ROGER 457... JUANCARLOS 472 MIKEL 415 DARIO 426 ABEL 380 MARCO 374
99 MIKEL 485 ANDER 419 ARTURO 419 MIKEL 444 JOAQUIN 446... ROGER 469 FRANCISCOJOSE 413 ALFONSO 418 MARTI 376 SALVADOR 354
100 GUILLEM 479 JUANJOSE 418 JOAQUIN 419 KEVIN 440 JOSEMARIA 446... FRANCISCOJOSE 455 AIMAR 402 ANDER 416 MATEO 373 MARTI 344
\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 ... 2006 2006 2005 \\\n", "campo nombre numero ... nombre numero nombre \n", "96 JUANANTONIO 467 ... BRUNO 478 ADAM \n", "97 AIMAR 464 ... SAUL 477 JON \n", "98 ROGER 457 ... JUANCARLOS 472 MIKEL \n", "99 JOAQUIN 446 ... ROGER 469 FRANCISCOJOSE \n", "100 JOSEMARIA 446 ... FRANCISCOJOSE 455 AIMAR \n", "\n", "a\u00f1o 2005 2004 2004 2003 2003 2002 2002 \n", "campo numero nombre numero nombre numero nombre numero \n", "96 427 MIKEL 431 IZAN 397 JOSEMIGUEL 389 \n", "97 419 MATEO 428 GUILLEM 385 ANDER 382 \n", "98 415 DARIO 426 ABEL 380 MARCO 374 \n", "99 413 ALFONSO 418 MARTI 376 SALVADOR 354 \n", "100 402 ANDER 416 MATEO 373 MARTI 344 \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", " \n", "
12345678910...919293949596979899100
a\u00f1o
2012 LUCIA MARIA PAULA DANIELA SARA CARLA MARTINA SOFIA JULIA ALBA... IRIS JANA ANE LIDIA CHLOE ARLET ONA IRATI JUDITH LUNA
2011 LUCIA PAULA MARIA SARA DANIELA CARLA SOFIA ALBA CLAUDIA MARTINA... MARA ANE TERESA FATIMA YAIZA ZOE BEATRIZ ONA NADIA LUNA
2010 LUCIA PAULA MARIA DANIELA SARA CARLA CLAUDIA SOFIA ALBA IRENE... MANUELA VALENTINA MARA ALEXIA ESTHER NADIA IRIS ALEXANDRA ANAMARIA TERESA
2009 LUCIA PAULA MARIA SARA DANIELA CARLA CLAUDIA MARTA IRENE SOFIA... MANUELA SARAY ANAMARIA IRIS MARA MONICA VALENTINA ESTHER NAHIA ALEXANDRA
2008 LUCIA MARIA PAULA SARA CARLA CLAUDIA LAURA MARTA IRENE ALBA... NADIA SARAY SONIA ALEXIA NAHIA MANUELA NOEMI NAIA ESTELA ANE
2007 LUCIA MARIA PAULA SARA LAURA CLAUDIA IRENE MARTA ALBA CARLA... IRIA FATIMA NADIA UXUE NAHIA REBECA ALEXANDRA MANUELA ANE ESTELA
2006 LUCIA MARIA PAULA LAURA CLAUDIA IRENE MARTA ALBA SARA CARLA... TERESA AYA NADIA SONIA JANA REBECA MARIADELCARMEN SORAYA ZAIRA GEMA
2005 LUCIA MARIA PAULA LAURA MARTA ALBA CLAUDIA CARLA ANDREA SARA... SARAY MARIADELCARMEN SONIA YANIRA NOEMI NADIA VERONICA IRIA IRATI AFRICA
2004 LUCIA MARIA PAULA LAURA MARTA ALBA ANDREA CLAUDIA SARA NEREA... ABRIL LEYRE ESTELA NOEMI IRIA GEMA ANE NADIA IRATI LUNA
2003 LUCIA MARIA PAULA LAURA MARTA ANDREA ALBA SARA CLAUDIA ANA... TANIA ELISA IRATI NADIA DIANA GEMA SUSANA SARAY ALEXIA GABRIELA
2002 MARIA LUCIA PAULA LAURA MARTA ALBA ANDREA SARA ANA NEREA... ALBAMARIA SALMA CANDELA PILAR VALERIA NADIA ESTELA JENNIFER IRATI INMACULADA
\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 ... 91 92 93 94 \\\n", "a\u00f1o ... \n", "2012 JULIA ALBA ... IRIS JANA ANE LIDIA \n", "2011 CLAUDIA MARTINA ... MARA ANE TERESA FATIMA \n", "2010 ALBA IRENE ... MANUELA VALENTINA MARA ALEXIA \n", "2009 IRENE SOFIA ... MANUELA SARAY ANAMARIA IRIS \n", "2008 IRENE ALBA ... NADIA SARAY SONIA ALEXIA \n", "2007 ALBA CARLA ... IRIA FATIMA NADIA UXUE \n", "2006 SARA CARLA ... TERESA AYA NADIA SONIA \n", "2005 ANDREA SARA ... SARAY MARIADELCARMEN SONIA YANIRA \n", "2004 SARA NEREA ... ABRIL LEYRE ESTELA NOEMI \n", "2003 CLAUDIA ANA ... TANIA ELISA IRATI NADIA \n", "2002 ANA NEREA ... ALBAMARIA SALMA CANDELA PILAR \n", "\n", " 95 96 97 98 99 100 \n", "a\u00f1o \n", "2012 CHLOE ARLET ONA IRATI JUDITH LUNA \n", "2011 YAIZA ZOE BEATRIZ ONA NADIA LUNA \n", "2010 ESTHER NADIA IRIS ALEXANDRA ANAMARIA TERESA \n", "2009 MARA MONICA VALENTINA ESTHER NAHIA ALEXANDRA \n", "2008 NAHIA MANUELA NOEMI NAIA ESTELA ANE \n", "2007 NAHIA REBECA ALEXANDRA MANUELA ANE ESTELA \n", "2006 JANA REBECA MARIADELCARMEN SORAYA ZAIRA GEMA \n", "2005 NOEMI NADIA VERONICA IRIA IRATI AFRICA \n", "2004 IRIA GEMA ANE NADIA IRATI LUNA \n", "2003 DIANA GEMA SUSANA SARAY ALEXIA GABRIELA \n", "2002 VALERIA NADIA ESTELA JENNIFER IRATI INMACULADA \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": 71 }, { "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+/AAAIABJREFUeJzs3X24rXdd3/n3FyPhQSREMQnPDIZCWjQQJcyMyKE8pV4V\nsLUhtLUoGTsaa5KOLZzYTqXtFBOcuQCZkpmWhzwUgSjVioZApNl22mkSUbCREEm0B0kgURMJnT54\nEfnOH+tesFzZT+tkr5zPb+/367r2te/7tz7r3p9732fts/PLun+nuhtJkiRJkiRp0UOOdQFJkiRJ\nkiTlcdJIkiRJkiRJ9+OkkSRJkiRJku7HSSNJkiRJkiTdj5NGkiRJkiRJuh8njSRJkiRJknQ/O04a\nVdUFVXVTVf1WVV0wjZ1YVddW1aer6iNVdcJC/qKqurWqbqmqly6MnzEd59aqeuvC+PFV9f5p/Pqq\nevJen6QkSZIkSZJWs+2kUVX9OeB/Ar4d+FbgL1bV04DDwLXd/XTgo9M+VXUa8CrgNOAs4O1VVdPh\nLgXO7e5TgVOr6qxp/Fzg7mn8zcAle3h+kiRJkiRJOgo7vdPoGcAN3f3fuvtPgF8F/jLwcuDyKXM5\n8Mpp+xXAe7v7S919BLgNOLOqTgEe1d03TrkrFp6zeKwPAC96YKckSZIkSZKkB2qnSaPfAp4/3Y72\nCOC7gCcAJ3X3XVPmLuCkaftxwO0Lz78dePwm43dM40yfPwvQ3fcB91bViUd3OpIkSZIkSdoLx233\nYHffUlWXAB8B/jPwCeBPljJdVb2+ipIkSZIkSXqwbTtpBNDd7wLeBVBV/4TZO4buqqqTu/vO6daz\n35/idwBPXHj6E6b8HdP28vj8OU8CPldVxwGP7u57lns4MSVJkiRJkrT3uru2emDbD+Cbps9PAj4F\nPBp4E/D6afwwcPG0fRqzdyM9FHgq8DtATY/dAJwJFHA1cNY0fh5w6bR9DvC+LXr0JmNv2Kn/0eb3\nczalR0I2pUdCNqXHaNmUHgnZlB4J2ZQeCdmUHqNlU3okZFN6JGRTeiRkU3qMlk3pkZBN6ZGQTemR\nkE3p8WBn2WS+Zf6x4zuNgJ+rqm8AvgSc1933VtXFwFVVdS5wBDh7+io3V9VVwM3AfVN+/g6h84DL\ngIcDV3f3NdP4O4Erq+pW4G5mE0e79ZQVsqvm93N2ncceLbvOY4+WXeex93N2ncceLbvOY4+WXeex\nR8uu89j7ObvOY4+WXeexR8uu89ijZdd57P2cXeexR8uu89ijZdd57NGy6zz2aFlgd7enfecmY/cA\nL94i/0bgjZuM/zrwrE3G/5hp0kmSJEmSJEkhVnmb1rH8YPPb0w6teIxd5/dzNqVHQjalR0I2pcdo\n2ZQeCdmUHgnZlB4J2ZQeo2VTeiRkU3okZFN6JGRTeoyWTemRkE3pkZBN6ZGQTenxYGfZ5va0+XpD\n8aqqe6uFmSRJkiRJkrSy7eZbHvJgl9lLVXVoXfn9nE3pkZBN6ZGQTekxWjalR0I2pUdCNqVHQjal\nx2jZlB4J2ZQeCdmUHgnZlB6jZVN6JGRTeiRkU3okZFN6JGTnhp40kiRJkiRJ0np4e5okSZIkSdIB\ntW9vT5MkSZIkSdJ6DD1p5L2JR5dN6ZGQTemRkE3pMVo2pUdCNqVHQjalR0I2pcdo2ZQeCdmUHgnZ\nlB4J2ZQeo2VTeiRkU3okZFN6JGRTeiRk54aeNJIkSZIkSdJ6uKaRJEmSJEnSAeWaRpIkSZIkSVrJ\n0JNG3pt4dNmUHgnZlB4J2ZQeo2VTeiRkU3okZFN6JGRTeoyWTemRkE3pkZBN6ZGQTekxWjalR0I2\npUdCNqVHQjalR0J2buhJI0mSJEmSJK2HaxpJkiRJkiQdUK5pJEmSJEmSpJUMPWnkvYlHl03pkZBN\n6ZGQTekxWjalR0I2pUdCNqVHQjalx2jZlB4J2ZQeCdmUHgnZlB6jZVN6JGRTeiRkU3okZFN6JGTn\nhp40kiRJkiRJ0nq4ppEkSZIkSdIB5ZpGkiRJkiRJWsnQk0bem3h02ZQeCdmUHgnZlB6jZVN6JGRT\neiRkU3okZFN6jJZN6ZGQTemRkE3pkZBN6TFaNqVHQjalR0I2pUdCNqVHQnZu6EkjSZIkSZIkrYdr\nGkmSJEmSJB1QrmkkSZIkSZKklQw9aeS9iUeXTemRkE3pkZBN6TFaNqVHQjalR0I2pUdCNqXHaNmU\nHgnZlB4J2ZQeCdmUHqNlU3okZFN6JGRTeiRkU3okZOeGnjSSJEmSJEnSerimkSRJkiRJ0gHlmkaS\nJEmSJElaydCTRt6beHTZlB4J2ZQeCdmUHqNlU3okZFN6JGRTeiRkU3qMlk3pkZBN6ZGQTemRkE3p\nMVo2pUdCNqVHQjalR0I2pUdCdm7oSSNJkiRJkiStx45rGlXVRcBfB74M3AT8APBI4P3Ak4EjwNnd\n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\nKT1Gy6b0SMim9EjIpvRIyKb0GC2b0iMhm9IjIZvSIyGb0mO0bEqPhGxKj4RsSo+EbEqPhOzc4JNG\nkiRJkiRJWgfXNJIkSZIkSTqgXNNIkiRJkiRJKxl80mhjpXTCfYEJ2ZQeCdmUHgnZlB6jZVN6JGRT\neiRkU3okZFN6jJZN6ZGQTemRkE3pkZBN6TFaNqVHQjalR0I2pUdCNqVHQnZu8EkjSZIkSZIkrYNr\nGkmSJEmSJB1QrmkkSZIkSZKklQw+abSxUjrhvsCEbEqPhGxKj4RsSo/Rsik9ErIpPRKyKT0Ssik9\nRsum9EjIpvRIyKb0SMim9Bgtm9IjIZvSIyGb0iMhm9IjITs3+KSRJEmSJEmS1sE1jSRJkiRJkg4o\n1zSSJEmSJEnSSgafNNpYKZ1wX2BCNqVHQjalR0I2pcdo2ZQeCdmUHgnZlB4J2ZQeo2VTeiRkU3ok\nZFN6JGRTeoyWTemRkE3pkZBN6ZGQTemRkJ0bfNJIkiRJkiRJ6+CaRpIkSZIkSQeUaxpJkiRJkiRp\nJYNPGm2slE64LzAhm9IjIZvSIyGb0mO0bEqPhGxKj4RsSo+EbEqP0bIpPRKyKT0Ssik9ErIpPUbL\npvRIyKb0SMim9EjIpvRIyM7tatKoqk6oqp+rqk9V1c1VdWZVnVhV11bVp6vqI1V1wkL+oqq6tapu\nqaqXLoyfUVU3TY+9dWH8+Kp6/zR+fVU9edUTkSRJkiRJ0t7Z1ZpGVXU58Kvd/a6qOg54JPD3gD/s\n7jdV1euBx3T34ao6DfgZ4NuBxwO/Apza3V1VNwJ/q7tvrKqrgZ/u7muq6jzgz3X3eVX1KuB7uvuc\npQ6uaSRJkiRJkrSH6oGsaVRVjwae393vAuju+7r7XuDlwOVT7HLgldP2K4D3dveXuvsIcBtwZlWd\nAjyqu2+cclcsPGfxWB8AXrTC+UmSJEmSJGmP7eb2tKcCf1BV766q36iqf15VjwRO6u67psxdwEnT\n9uOA2xeefzuzdxwtj98xjTN9/izMJqWAe6vqxJ2rbeyi/lcl3BeYkE3pkZBN6ZGQTekxWjalR0I2\npUdCNqVHQjalx2jZlB4J2ZQeCdmUHgnZlB6jZVN6JGRTeiRkU3okZFN6JGTnjttl5jnMbiv7tap6\nC3B4MTDderbzfW4PUFVdBhyZ7b1lGj20+Pih7t6Yb0/dFvdPZ5pp2uLxr+wDp1fVlo8f7f5i113k\n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\npe/yce/3y+mqPVjhZ+cWX+d+P38erCw7/Nw8mmOzwn/87Pa4rGnSYZOv83xm/2PhpbvouuvsOo89\nZf/+mo677u/FjusvbHds4Ey+um7lI5n9DvHL02vv0UvZ5y1kH8FssuCXmK3DtUp2eZ2yXWe3yP/U\n9Of5gfbY7HtxNOe3U3a33+NHbnfcKXM+8MRd/pm5ICD7p/qy8HvLXh53Def3pBV67DZ7PLO1V18y\n7f91Zndr/Aj3/z15nn3xtP/XFrIPPdrsHhz7bwD/eg87v2ST7CrH3Sq7eNy3A39rObuLHpt9757G\n7H94/TSz/4H0w2zyOl3I/l1m/yPozcAPAV9/jLI/Dfzf05/XTbOb5Fc59vx7sY7z2+l7/Lpd9j2N\n2eTR26aPw0y/C6/yMV9PQdozVfUD3f3uXWZf293vOhbZqnoEswWpb1pj51WOu67s/frW7F8Y/BFm\n/6fn2cz+4+gXpsc+3t3PNvunsyk9avYvPr6Q2Rpr1zG7zfGXgZcAH+zun1p3NqVHQvZo8suq6sru\n/r5Nxj8INLN3yc79eWa/uHZ3v3zd2U06PYLZZM33bvH4UR97ev4D/l6sctwtsld099/YZPzG7n7u\ntP2DzF6zP89soclf6u6fPJrsOo89WnbNPW5mdpvlfVX1z5n9q7U/x2yy/lu6+y8lZVN6JGSn/L3A\nf2G2qOt7gZ/t7v+/vftpjfKK4jj+O4mtf5pVFymCYlbuhXRTKA20i4LShW/AvRtXBdE34Ma3oSC4\nCt2UQsimm1LSUrqUBgtCKK0KihLSHBf3kYzz995n5mbOM/l+4EKY5zeHMzOLkPtk7vlHQ/Rknyjd\nue9KtuS1TcxG6cPMHij9fjyntEG/onSG6TeS5O43amej9DGH7NdK35aY5r24pfTtmm2lm36/Kd3w\nui7pprtvjcheVboh9ELprNp5ZMf2OyY/de0ZvL6cumP7nSkv3GVisSYtjTjnKWo2Sh/HmdXghMFf\nNXrCYMk0woXNRulDZRMfq2Sj9BEh26L2ptLhy5s96/X7x/uyRRM7x2Q3pshm91uzduF7UVK3qIee\nnydNRc3O1qzdtWzlPkom1c49G6WPCNn3n7UypweTjdWHyiY5V8lG6SNCtkXtkunancpG6aNidibT\nzt1dpwS0YGZ/jLn8WbRsRn61Uh8ldWv1MPBeKN11eCVJ7r5rZl9Jemxml/Thnfxh2Y0Tmo3Sx767\nH0g6MLMn7v6yed4bMzs8pmyUPiJkS/MXdDSQ4FDp811XmqrYb13p6wJ3JX3v7jtm9tbdt48xW9Jv\nzdq16pZkl83s0yaz7M1ddXd/bWYHU2Rr1u5atmbtP+3oP29/N7PP3f0XM7ssaT9gNkofEbKSJHc/\nVJpA+aOZfayjKYn3lc4iJduXDdLHkpmdVvoD96zSGa7/SjqjtPGkY8hG6SNCtjTvSgOl/m+ufyJJ\n7v7UzD7qeDZKH7Wyj5SmjW8oHS3gZnZeaXP3kdKmb55Ru0ks1rglaU/pazRrQ9azaNkofUTINvkt\n5U8YJBuoDxVMfKyVjdJHhGyL2stKh+z/JOlK89hf/TX7njNxYmetbJt+a9aedd3C7K7yp6JmZ2vW\n7lq2ch8lk2rnno3SR4Rsk8+eHkw2Vh8qm+RcJRuljwjZFrVvKX+6dqeyUfqomM2e2DtpZQdZrN6l\n9K+oX4649jBaNkofEbLNYyUTBskG6kMFEx9rZaP0ESHbJt9cy97c6XlO9sTOWWfb9Fuz9qzrtn19\nzXNHTkWdJluzdteys6ytjEm1kbJR+ph3VgXTg8mG7GNN+ZOcq2Sj9BEh26J21nTtLmaj9FEjq4KJ\nvZMWB2EDADAnZnZN0hfufmfeveSo2W+t2iV1u/Z5AAAADNN8ffu2pO90dFzJntJZjvfc/b/sWmwa\nAQAAAAAALD4rmMQtsWkEAAAAAABwIpjZ3+5+MTfP9DQAAAAAAIAFYeXTtUdi0wgAAAAAAGBxrEr6\nVtLzIdd+LinEphEAAAAAAMDi+EHSirvv9F8ws+2SQpxpBAAAAAAAgAFL824AAAAAAAAA8bBpBAAA\nAAAAgAFsGgEAAAAAAGAAm0YAAAAAAAAYwKYRAAAAAAAABrwD/OD76BfQVXUAAAAASUVORK5CYII=\n", "text": [ "" ] } ], "prompt_number": 72 }, { "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\n", "69759.0\n" ] }, { "metadata": {}, "output_type": "display_data", "png": "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\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", " \n", "
12345678910...919293949596979899100
a\u00f1o
2012 DANIEL HUGO ALEJANDRO PABLO ALVARO ADRIAN DAVID DIEGO MARIO JAVIER... FRANCISCOJAVIER YAGO CESAR ADRIA OMAR YERAY GAEL JON MIKEL GUILLEM
2011 ALEJANDRO DANIEL PABLO HUGO ALVARO ADRIAN DAVID DIEGO JAVIER MARIO... JORDI IAN OMAR GUILLEM CESAR GAEL YERAY JON ANDER JUANJOSE
2010 DANIEL ALEJANDRO PABLO HUGO ALVARO ADRIAN DAVID JAVIER DIEGO MARIO... GUILLEM IAN CESAR YERAY MIKEL JUANJOSE JON NIL ARTURO JOAQUIN
2009 DANIEL ALEJANDRO PABLO HUGO ALVARO ADRIAN DAVID JAVIER SERGIO DIEGO... JUANMANUEL ALEIX CESAR ROGER JOSELUIS YERAY JOSEMARIA SERGI MIKEL KEVIN
2008 DANIEL ALEJANDRO PABLO DAVID ADRIAN HUGO ALVARO JAVIER DIEGO SERGIO... GERARD SERGI ALEIX ENEKO CESAR JUANANTONIO AIMAR ROGER JOAQUIN JOSEMARIA
2007 DANIEL ALEJANDRO PABLO DAVID ADRIAN ALVARO HUGO JAVIER DIEGO SERGIO... JUANMANUEL JOSEMARIA CHRISTIAN ALEIX ISAAC JUANANTONIO CESAR AIMAR ANDER XAVIER
2006 ALEJANDRO DANIEL PABLO DAVID ADRIAN ALVARO JAVIER SERGIO HUGO DIEGO... YERAY AIMAR JUANANTONIO ERIK JOAQUIN BRUNO SAUL JUANCARLOS ROGER FRANCISCOJOSE
2005 ALEJANDRO DANIEL PABLO DAVID ADRIAN JAVIER ALVARO SERGIO CARLOS MARCOS... ISAAC JOAQUIN ALEIX ANDER BRUNO ADAM JON MIKEL FRANCISCOJOSE AIMAR
2004 ALEJANDRO DAVID DANIEL PABLO ADRIAN ALVARO JAVIER SERGIO CARLOS MARCOS... CESAR GUILLEM MARTI ALBERT JONATHAN MIKEL MATEO DARIO ALFONSO ANDER
2003 ALEJANDRO DANIEL PABLO DAVID JAVIER ADRIAN ALVARO SERGIO CARLOS HUGO... RICARDO MARCO ISAAC CESAR ANDER IZAN GUILLEM ABEL MARTI MATEO
2002 ALEJANDRO PABLO DANIEL DAVID ADRIAN JAVIER ALVARO SERGIO CARLOS MARIO... GUILLEM RICARDO CESAR ISAAC RAMON JOSEMIGUEL ANDER MARCO SALVADOR MARTI
\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 ... 91 92 93 \\\n", "a\u00f1o ... \n", "2012 MARIO JAVIER ... FRANCISCOJAVIER YAGO CESAR \n", "2011 JAVIER MARIO ... JORDI IAN OMAR \n", "2010 DIEGO MARIO ... GUILLEM IAN CESAR \n", "2009 SERGIO DIEGO ... JUANMANUEL ALEIX CESAR \n", "2008 DIEGO SERGIO ... GERARD SERGI ALEIX \n", "2007 DIEGO SERGIO ... JUANMANUEL JOSEMARIA CHRISTIAN \n", "2006 HUGO DIEGO ... YERAY AIMAR JUANANTONIO \n", "2005 CARLOS MARCOS ... ISAAC JOAQUIN ALEIX \n", "2004 CARLOS MARCOS ... CESAR GUILLEM MARTI \n", "2003 CARLOS HUGO ... RICARDO MARCO ISAAC \n", "2002 CARLOS MARIO ... GUILLEM RICARDO CESAR \n", "\n", " 94 95 96 97 98 99 \\\n", "a\u00f1o \n", "2012 ADRIA OMAR YERAY GAEL JON MIKEL \n", "2011 GUILLEM CESAR GAEL YERAY JON ANDER \n", "2010 YERAY MIKEL JUANJOSE JON NIL ARTURO \n", "2009 ROGER JOSELUIS YERAY JOSEMARIA SERGI MIKEL \n", "2008 ENEKO CESAR JUANANTONIO AIMAR ROGER JOAQUIN \n", "2007 ALEIX ISAAC JUANANTONIO CESAR AIMAR ANDER \n", "2006 ERIK JOAQUIN BRUNO SAUL JUANCARLOS ROGER \n", "2005 ANDER BRUNO ADAM JON MIKEL FRANCISCOJOSE \n", "2004 ALBERT JONATHAN MIKEL MATEO DARIO ALFONSO \n", "2003 CESAR ANDER IZAN GUILLEM ABEL MARTI \n", "2002 ISAAC RAMON JOSEMIGUEL ANDER MARCO SALVADOR \n", "\n", " 100 \n", "a\u00f1o \n", "2012 GUILLEM \n", "2011 JUANJOSE \n", "2010 JOAQUIN \n", "2009 KEVIN \n", "2008 JOSEMARIA \n", "2007 XAVIER \n", "2006 FRANCISCOJOSE \n", "2005 AIMAR \n", "2004 ANDER \n", "2003 MATEO \n", "2002 MARTI \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\n", "20094.0\n" ] }, { "metadata": {}, "output_type": "display_data", "png": "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\ntS8Bt6WUUkQ8CtxfPv9zwMdTSp9v8T1T6sB2dJKWJiLG67+gJHWPc0+qhnNPqoZzT2pPWZa2gblV\nRtvJK8YOzTpOjI8vEPDQubxlwSCpfKOfBf4xcAn4L8BPAGPAZ4GbyMnWO1JKJ8r9fw74cWAKeG9K\n6Qvl9nvJQdQo8HBK6f7lfGCSJEmSJEm9rlaL1cA1zAyM6r2oZwdGr4yPp8kr+T5dC5K6zSBJkiRJ\nkiQNmlJltJmZPYx2lNuOMjc0OrNYldFSGCRJ6ijLjKVqOPekajj3pGo497RS1GqxltbNry8wNzA6\nOj6eppf7nDqVtyzWbFuSJEmSJEkt1GqxCtjG3MBoHXljskPl8uvAofHxdL6iU+0YK5IkSZIkSZIW\nUavFfM2vTzO3yuh4J5eldYJL2yRJkiRJkjqsVothWje/XsXMsOgwcHh8PF2s6FSXxCBJUke5Xl2q\nhnNPqoZzT6qGc0+9pDS/3sTc5tdbgGPMrTI63WtVRkthjyRJkiRJkqQ21GqxhtbNrydpBEVPAX8O\nHOlG8+t+ZUWSJEmSJEkaCKX59VbmBkYbKEvRaKoyGh9P5yo61a5zaZskSZIkSVqxarVYz9wqo2uA\nM7Rufn2polPtCQZJkjrK9epSNZx7UjWce1I1nHu6EqX59XbmNr8eZmbj60Pk5tcXKjrVnmaPJEmS\nJEmSNDBK8+uNzG1+vRU4TiM0erRcnurn5tf9yookSZIkSZLUVbVajDB3WdoOYIqZS9IOA6+Mj6ep\nik51YFiRJEmSJEmSelppfr2FuYHRBuAIjcBoD7n59dmKTlVtsiJJEuB6dakqzj2p+2q1GHr723nD\n8ePpkarPRVpp/Ls32Gq1WMfcKqNrgbPMbX59bKU3v+42K5IkSZKkNtVqsRq4DbgLuONHf5Tba7V4\nLfnd8KOzLlf8zj6StJBaLYZo3fx6hMZytJeBx8nNrycqOlUtAyuSJEmSNJBqtRgF7iSHR7cAB8hL\nJ/YAp4ExYBv5xVD9cjt5ucUJWoRM4+PpXHcfhSR1RwmH1gBrZx3Nt9WXqG0j/56cXWV00ubXvatT\neYtBkiRJkgZGrRYbycHRq4Hrgb3AN4CnxsfT+Ta/xmryDkGtQqZp5lYw1auYpjv6YCSpTWW3s9XM\nHwC1Gs++bQiYAC6Uy4kW45PkwOiV8fE02Z1Hp04xSJLUUa5Xl6rh3JOuXq0W19AIj7YAT5HDo2fn\n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\n", "text": [ "" ] } ], "prompt_number": 66 }, { "cell_type": "code", "collapsed": true, "input": [], "language": "python", "metadata": {}, "outputs": [] } ], "metadata": {} } ] }