{ "cells": [ { "attachments": { "logpypan.png": { "image/png": "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" } }, "cell_type": "markdown", "metadata": {}, "source": [ "# *Introducción a Pandas en los cuadernos de Jupyter*\n", "![logpypan.png](attachment:logpypan.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### La estructura de Datos `Serie`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`Arreglo` unidimensional con etiquetas en los ejes (incluidas series de tiempo). Los parámetros de una `Serie` son: `data` (matriz, diccionario o escalar), `index` (arreglo de índices), `dtype` (`numpy.dtype` o `None`) y `copy` (booleano o por defecto `False`)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Importamos la biblioteca `Pandas`" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "pd.Series?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Podemos convertir una `lista` en una `serie` y pandas asigna de manera inmediata una lista de índices que empieza en 0." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 Tigre\n", "1 Oso\n", "2 Camello\n", "dtype: object" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "animales = ['Tigre', 'Oso', 'Camello']\n", "pd.Series(animales)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 1\n", "1 2\n", "2 3\n", "dtype: int64" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "numeros = [1, 2, 3]\n", "pd.Series(numeros)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 Tigre\n", "1 Oso\n", "2 None\n", "dtype: object" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "animales = ['Tigre', 'Oso', None]\n", "pd.Series(animales)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Es importante saber como `NumPy` y `Pandas` manejan los datos faltantes. En Python tenemos el tipo `None` para indicar un dato faltante. Si tenemos una lista de números, `Pandas` automáticamente convierte este valor `None` en un valor designado como `NaN`, que significa `Not a Number`." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 1.0\n", "1 2.0\n", "2 NaN\n", "dtype: float64" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "numeros = [1, 2, None]\n", "pd.Series(numeros)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Importamos la biblioteca `NumPy`. También es importante saber que `NaN` no es `None`. Cuando hacemos un test para saber si `NaN` es `NaN` tambien obtendremos `False`." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import numpy as np\n", "np.nan == None" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.nan == np.nan" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Se necesita la función especial `isnan` de `NumPy` para chequear la presencia de un `no número` en nuestros datos." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n", "True\n", "True\n" ] } ], "source": [ "print(np.isnan(np.nan))\n", "print(None is None)\n", "print(np.nan is np.nan)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "¿Cómo creamos una `serie` en `Pandas`? Podemos utilizar una estructura de datos `diccionario` con sus `claves` y convertirlo en una `serie`, donde los índices de la `serie` son las claves del diccionario." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Béisbol Cuba\n", "Capoeira Brasil\n", "Corrida de Toros España\n", "Golf Escocia\n", "Pelota Vasca País Vasco\n", "Rayuela Chile\n", "Rugby Gales\n", "Sumo Japón\n", "dtype: object" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "deportes = {'Capoeira': 'Brasil',\n", " 'Rayuela': 'Chile',\n", " 'Pelota Vasca': 'País Vasco',\n", " 'Béisbol': 'Cuba',\n", " 'Rugby': 'Gales',\n", " 'Golf': 'Escocia',\n", " 'Corrida de Toros': 'España',\n", " 'Sumo': 'Japón'}\n", "s = pd.Series(deportes)\n", "s" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Luego, podemos chequear la lista de índices con el atributo `.index`" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Index(['Béisbol', 'Capoeira', 'Corrida de Toros', 'Golf', 'Pelota Vasca',\n", " 'Rayuela', 'Rugby', 'Sumo'],\n", " dtype='object')" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s.index" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "En este otro ejemplo, pasamos directamente una lista con su conjunto de índices para crear la `Serie`." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "India Tigre\n", "America Oso\n", "Africa Camello\n", "dtype: object" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s = pd.Series(['Tigre', 'Oso', 'Camello'], index=['India', 'America', 'Africa'])\n", "s" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Aquí tenemos un ejemplo de un elemento nuevo en la lista de índices que no tiene un valor asignado, no existe un país asociado al índice `Natación` y `Pandas` representa este valor faltante con `NaN`. " ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Capoeira Brasil\n", "Sumo Japón\n", "Pelota Vasca País Vasco\n", "Natación NaN\n", "dtype: object" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "deportes = {'Capoeira': 'Brasil',\n", " 'Rayuela': 'Chile',\n", " 'Pelota Vasca': 'País Vasco',\n", " 'Béisbol': 'Cuba',\n", " 'Rugby': 'Gales',\n", " 'Golf': 'Escocia',\n", " 'Corrida de Toros': 'España',\n", " 'Sumo': 'Japón'}\n", "s = pd.Series(deportes, index=['Capoeira', 'Sumo', 'Pelota Vasca', 'Natación'])\n", "s" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Búsqueda en una `Serie`" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Béisbol Cuba\n", "Capoeira Brasil\n", "Corrida de Toros España\n", "Golf Escocia\n", "Pelota Vasca País Vasco\n", "Rayuela Chile\n", "Rugby Gales\n", "Sumo Japón\n", "dtype: object" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "deportes = {'Capoeira': 'Brasil',\n", " 'Rayuela': 'Chile',\n", " 'Pelota Vasca': 'País Vasco',\n", " 'Béisbol': 'Cuba',\n", " 'Rugby': 'Gales',\n", " 'Golf': 'Escocia',\n", " 'Corrida de Toros': 'España',\n", " 'Sumo': 'Japón'}\n", "s = pd.Series(deportes)\n", "s" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Podemos hacer búsquedas en las `series` por posición de índices o por etiqueta de índices. Si queremos hacer búsqueda por ubicación numérica (empezando desde 0) utilizamos el atributo `iloc`. Si por otra parte, hacemos búqueda por etiqueta de índice entonces usamos el atributo `loc`." ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'País Vasco'" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s.iloc[4]" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'País Vasco'" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s.loc['Pelota Vasca']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "`Pandas` trata de que el código sea más legible. Si le pasamos por parámetro un valor numérico a la `Serie` esta se comportará como si la búsqueda se hace con el atributo `iloc`, si en cambio le pasamos un objeto, hará la búsqueda por etiqueta como con el atributo `loc`." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'País Vasco'" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s[4]" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'País Vasco'" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s['Pelota Vasca']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "¿Qué pasa cuando tenemos una lista de índices que son enteros?" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "99 Brasil\n", "100 Chile\n", "101 País Vasco\n", "102 Cuba\n", "103 Gales\n", "104 Escocia\n", "105 España\n", "106 Japón\n", "dtype: object" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "deportes = {99: 'Brasil',\n", " 100: 'Chile',\n", " 101: 'País Vasco',\n", " 102: 'Cuba',\n", " 103: 'Gales',\n", " 104: 'Escocia',\n", " 105: 'España',\n", " 106: 'Japón'}\n", "s = pd.Series(deportes)\n", "s" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Cuando tenemos un caso como este es más seguro utilizar los atributos `iloc` o `loc` según sea el caso. " ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "scrolled": true }, "outputs": [ { "ename": "KeyError", "evalue": "0", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0ms\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;31m#Esta instrucción no llamará s.iloc[0] como esperaríamos y va a generar un error\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m/anaconda3/lib/python3.6/site-packages/pandas/core/series.py\u001b[0m in \u001b[0;36m__getitem__\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 621\u001b[0m \u001b[0mkey\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcom\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_apply_if_callable\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 622\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 623\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mindex\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_value\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 624\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 625\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mis_scalar\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mresult\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m/anaconda3/lib/python3.6/site-packages/pandas/core/indexes/base.py\u001b[0m in \u001b[0;36mget_value\u001b[0;34m(self, series, key)\u001b[0m\n\u001b[1;32m 2558\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2559\u001b[0m return self._engine.get_value(s, k,\n\u001b[0;32m-> 2560\u001b[0;31m tz=getattr(series.dtype, 'tz', None))\n\u001b[0m\u001b[1;32m 2561\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mKeyError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2562\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m0\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minferred_type\u001b[0m \u001b[0;32min\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m'integer'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'boolean'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32mpandas/_libs/index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_value\u001b[0;34m()\u001b[0m\n", "\u001b[0;32mpandas/_libs/index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_value\u001b[0;34m()\u001b[0m\n", "\u001b[0;32mpandas/_libs/index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n", "\u001b[0;32mpandas/_libs/hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.Int64HashTable.get_item\u001b[0;34m()\u001b[0m\n", "\u001b[0;32mpandas/_libs/hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.Int64HashTable.get_item\u001b[0;34m()\u001b[0m\n", "\u001b[0;31mKeyError\u001b[0m: 0" ] } ], "source": [ "s[0] #Esta instrucción no llamará s.iloc[0] como esperaríamos y va a generar un error" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s.iloc[0]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s.loc[99]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Ya que sabemos hacer búsquedas en las `Series`, ahora vamos a trabajar con los datos (encontrar valores, resumir los datos o transformarlos)." ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 105.0\n", "1 223.0\n", "2 5.0\n", "3 102.0\n", "4 27.0\n", "5 -126.0\n", "dtype: float64" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s = pd.Series([105.00, 223.00, 5, 102.00, 27, -126])\n", "s" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Una forma de trabajar es iterar sobre un conjunto de datos e invocar una operación de interés" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "336.0\n" ] } ], "source": [ "total = 0\n", "for elemento in s:\n", " total+=elemento\n", "print(total)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Con `NumPy` podemos tener acceso a las funciones universales binarias o unarias (vectorizadas, cálculos más rápidos). En este ejemplo, `np.sum` hará la suma de todos los elementos en la `serie`." ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "336.0\n" ] } ], "source": [ "import numpy as np\n", "\n", "total = np.sum(s)\n", "print(total)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "También podemos generar una `serie` grande de números aleatorios y con el método `.head()` podemos desplegar un encabezado con los 5 primeros elementos de la `serie` y con `len` chequear el tamaño de la misma." ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 42\n", "1 872\n", "2 956\n", "3 330\n", "4 9\n", "dtype: int64\n", "10000\n" ] } ], "source": [ "s = pd.Series(np.random.randint(0,1000,10000))\n", "print(s.head())\n", "print(len(s))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Los cuadernos de `Jupyter` tienen **funciones mágicas** que pueden ser útiles. Una de ellas es `%%timeit` que nos servirá para ver cuál de los dos métodos para sumar elementos de una `serie` es más rápido.\n", "Basta con tipear el símbolo `%` y la tecla `Tab` para obtener una lista de las **funciones mágicas** de `Jupyter`." ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "803 µs ± 52.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" ] } ], "source": [ "%%timeit -n 100\n", "sumar = 0\n", "for elemento in s:\n", " sumar+=elemento" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "128 µs ± 21.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" ] } ], "source": [ "%%timeit -n 100\n", "sumar = np.sum(s)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "`NumPy` y `Pandas` tienen el `broadcasting`, se puede aplicar una operación a cada valor de la `serie` y modificarla." ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 44\n", "1 874\n", "2 958\n", "3 332\n", "4 11\n", "dtype: int64" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s+=2 #Suma 2 a cada elemento de la serie usando broadcasting\n", "s.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Una manera poco eficiente de hacer esto es iterar sobre cada elemento de la `serie` para hacer la suma. El método `.iteritems()` devuelve un iterador sobre los pares `(key, value)` (clave, valor) de un diccionario, en este caso de nuestra `serie` s." ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/anaconda3/lib/python3.6/site-packages/ipykernel_launcher.py:2: FutureWarning: set_value is deprecated and will be removed in a future release. Please use .at[] or .iat[] accessors instead\n", " \n" ] }, { "data": { "text/plain": [ "0 46\n", "1 876\n", "2 960\n", "3 334\n", "4 13\n", "dtype: int64" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "for etiqueta, valor in s.iteritems():\n", " s.set_value(etiqueta, valor+2)\n", "s.head()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%timeit -n 10\n", "s = pd.Series(np.random.randint(0,1000,10000))\n", "for etiqueta, valor in s.iteritems():\n", " s.loc[etiqueta]= valor+2" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%timeit -n 10\n", "s = pd.Series(np.random.randint(0,1000,10000))\n", "s+=2\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Podemos agregar elementos a una `serie` de la siguiente forma:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 1\n", "1 2\n", "2 3\n", "Animal Oso\n", "dtype: object" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import pandas as pd\n", "s = pd.Series([1, 2, 3])\n", "s.loc['Animal'] = 'Oso'\n", "s" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Este es un ejemplo de una `serie` donde los valores del conjunto de índices no son únicos. Esto hace que las tablas de datos funcionen diferente y es por ello que agregar nuevos elementos debe hacerse con el método `append`, que en primera instancia, no modificará la `serie` sino que devuelve una nueva `serie` con los elementos que se agregaron." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "deportes_originales = pd.Series({'Capoeira': 'Brasil',\n", " 'Rayuela': 'Chile',\n", " 'Pelota Vasca': 'País Vasco',\n", " 'Béisbol': 'Cuba',\n", " 'Rugby': 'Gales',\n", " 'Golf': 'Escocia',\n", " 'Corrida de Toros': 'España',\n", " 'Sumo': 'Japón'})\n", "paises_que_aman_el_beisbol = pd.Series(['Venezuela',\n", " 'USA',\n", " 'Cuba',\n", " 'Puerto Rico',\n", " 'Dominicana'], \n", " index=['Béisbol',\n", " 'Béisbol',\n", " 'Béisbol',\n", " 'Béisbol',\n", " 'Béisbol'])\n", "todos_los_paises = deportes_originales.append(paises_que_aman_el_beisbol)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Béisbol Cuba\n", "Capoeira Brasil\n", "Corrida de Toros España\n", "Golf Escocia\n", "Pelota Vasca País Vasco\n", "Rayuela Chile\n", "Rugby Gales\n", "Sumo Japón\n", "dtype: object" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "deportes_originales" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Béisbol Venezuela\n", "Béisbol USA\n", "Béisbol Cuba\n", "Béisbol Puerto Rico\n", "Béisbol Dominicana\n", "dtype: object" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "paises_que_aman_el_beisbol" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Béisbol Cuba\n", "Capoeira Brasil\n", "Corrida de Toros España\n", "Golf Escocia\n", "Pelota Vasca País Vasco\n", "Rayuela Chile\n", "Rugby Gales\n", "Sumo Japón\n", "Béisbol Venezuela\n", "Béisbol USA\n", "Béisbol Cuba\n", "Béisbol Puerto Rico\n", "Béisbol Dominicana\n", "dtype: object" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "todos_los_paises" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Béisbol Cuba\n", "Béisbol Venezuela\n", "Béisbol USA\n", "Béisbol Cuba\n", "Béisbol Puerto Rico\n", "Béisbol Dominicana\n", "dtype: object" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "todos_los_paises.loc['Béisbol']" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "### La estructura de datos `DataFrame`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "El `DataFrame` o Tabla de Datos es el corazón de la biblioteca `Pandas`. Es el objeto primario para el análisis de datos. Es una especie de **arreglo bidimensional** con etiquetas en los ejes. En este ejemplo, crearemos tres diccionarios que serán luego las filas de nuestro `DataFrame`." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/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", "
Artículo compradoCostoNombre
Tienda 1Libro1200Adelis
Tienda 1Raspberry pi 315000Miguel
Tienda 2Balón5000Jaime
\n", "
" ], "text/plain": [ " Artículo comprado Costo Nombre\n", "Tienda 1 Libro 1200 Adelis\n", "Tienda 1 Raspberry pi 3 15000 Miguel\n", "Tienda 2 Balón 5000 Jaime" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import pandas as pd\n", "compra_1 = pd.Series({'Nombre': 'Adelis',\n", " 'Artículo comprado': 'Libro',\n", " 'Costo': 1200})\n", "compra_2 = pd.Series({'Nombre': 'Miguel',\n", " 'Artículo comprado': 'Raspberry pi 3',\n", " 'Costo': 15000})\n", "compra_3 = pd.Series({'Nombre': 'Jaime',\n", " 'Artículo comprado': 'Balón',\n", " 'Costo': 5000})\n", "df = pd.DataFrame([compra_1, compra_2, compra_3], index=['Tienda 1', 'Tienda 1', 'Tienda 2'])\n", "df.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "En un `DataFrame` también se puede extraer información usando los atributos `loc` y `iloc`." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Artículo comprado Balón\n", "Costo 5000\n", "Nombre Jaime\n", "Name: Tienda 2, dtype: object" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.loc['Tienda 2']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "También podemos chequear el tipo de dato usando la función `type` de Python." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "pandas.core.series.Series" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(df.loc['Tienda 2'])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "En los `DataFrame` también se pueden tener listas de índices no únicos. En el ejemplo, hay dos índices con el mismo nombre `Tienda 1`." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/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", "
Artículo compradoCostoNombre
Tienda 1Libro1200Adelis
Tienda 1Raspberry pi 315000Miguel
\n", "
" ], "text/plain": [ " Artículo comprado Costo Nombre\n", "Tienda 1 Libro 1200 Adelis\n", "Tienda 1 Raspberry pi 3 15000 Miguel" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.loc['Tienda 1']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "También podemos seleccionar columnas agregando un parámetro extra al atributo `loc`." ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "Tienda 1 1200\n", "Tienda 1 15000\n", "Name: Costo, dtype: int64" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.loc['Tienda 1', 'Costo']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Usar el atributo `.T` para obtener la transpuesta del `DataFrame` o Tabla de Datos." ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/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", "
Tienda 1Tienda 1Tienda 2
Artículo compradoLibroRaspberry pi 3Balón
Costo1200150005000
NombreAdelisMiguelJaime
\n", "
" ], "text/plain": [ " Tienda 1 Tienda 1 Tienda 2\n", "Artículo comprado Libro Raspberry pi 3 Balón\n", "Costo 1200 15000 5000\n", "Nombre Adelis Miguel Jaime" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.T" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Usando `.T.loc[]` se puede seleccionar una columna usando como parámetro la etiqueta de su nombre. " ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Tienda 1 1200\n", "Tienda 1 15000\n", "Tienda 2 5000\n", "Name: Costo, dtype: object" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.T.loc['Costo']" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Tienda 1 1200\n", "Tienda 1 15000\n", "Tienda 2 5000\n", "Name: Costo, dtype: int64" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df['Costo']" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Tienda 1 1200\n", "Tienda 1 15000\n", "Name: Costo, dtype: int64" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.loc['Tienda 1']['Costo']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "`loc` también tiene soporte para rebanar o seleccionar del `DataFrame` con la notación `[]`" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/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", "
NombreCosto
Tienda 1Adelis1200
Tienda 1Miguel15000
Tienda 2Jaime5000
\n", "
" ], "text/plain": [ " Nombre Costo\n", "Tienda 1 Adelis 1200\n", "Tienda 1 Miguel 15000\n", "Tienda 2 Jaime 5000" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.loc[:,['Nombre', 'Costo']]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "También podemos eliminar datos del `DataFrame` con la función `drop()`. Esta función toma un solo parámetro que es el índice del conjunto de datos que deseamos eliminar. " ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Artículo compradoCostoNombre
Tienda 2Balón5000Jaime
\n", "
" ], "text/plain": [ " Artículo comprado Costo Nombre\n", "Tienda 2 Balón 5000 Jaime" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.drop('Tienda 1')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Podemos ver que nuestro `DataFrame` original sigue intacto. Solo hicimos una **extracción** de información." ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/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", "
Artículo compradoCostoNombre
Tienda 1Libro1200Adelis
Tienda 1Raspberry pi 315000Miguel
Tienda 2Balón5000Jaime
\n", "
" ], "text/plain": [ " Artículo comprado Costo Nombre\n", "Tienda 1 Libro 1200 Adelis\n", "Tienda 1 Raspberry pi 3 15000 Miguel\n", "Tienda 2 Balón 5000 Jaime" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "También podemos hacer una copia del `DataFrame` con la función `copy()` para guardar la extracción de información. " ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Artículo compradoCostoNombre
Tienda 2Balón5000Jaime
\n", "
" ], "text/plain": [ " Artículo comprado Costo Nombre\n", "Tienda 2 Balón 5000 Jaime" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "copiar_df = df.copy()\n", "copiar_df = copiar_df.drop('Tienda 1')\n", "copiar_df" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [], "source": [ "copiar_df.drop?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Podemos eliminar una columna de manera sencilla, usando simplemente la palabra clave `del` y el índice o nombre de la comuna. " ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Artículo compradoNombre
Tienda 2BalónJaime
\n", "
" ], "text/plain": [ " Artículo comprado Nombre\n", "Tienda 2 Balón Jaime" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "del copiar_df['Costo']\n", "copiar_df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Finalmente, es muy sencillo agregar una columna al `DataFrame`." ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/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", "
Artículo compradoCostoNombreUbicación
Tienda 1Libro1200AdelisVenezuela
Tienda 1Raspberry pi 315000MiguelChile
Tienda 2Balón5000JaimeArgentina
\n", "
" ], "text/plain": [ " Artículo comprado Costo Nombre Ubicación\n", "Tienda 1 Libro 1200 Adelis Venezuela\n", "Tienda 1 Raspberry pi 3 15000 Miguel Chile\n", "Tienda 2 Balón 5000 Jaime Argentina" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df['Ubicación'] = ['Venezuela', 'Chile', 'Argentina']\n", "df" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "### Lectura de un `DataFrame`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Usemos `!cat` para leer un archivo de formato `CSV`. Nota: `!cat` funciona para **Linux** y **Mac** pero puede no funcionar para **Windows** :(" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15\r\n", ",№ Summer,01 !,02 !,03 !,Total,№ Winter,01 !,02 !,03 !,Total,№ Games,01 !,02 !,03 !,Combined total\r\n", "Afghanistan (AFG),13,0,0,2,2,0,0,0,0,0,13,0,0,2,2\r\n", "Algeria (ALG),12,5,2,8,15,3,0,0,0,0,15,5,2,8,15\r\n", "Argentina (ARG),23,18,24,28,70,18,0,0,0,0,41,18,24,28,70\r\n", "Armenia (ARM),5,1,2,9,12,6,0,0,0,0,11,1,2,9,12\r\n", "Australasia (ANZ) [ANZ],2,3,4,5,12,0,0,0,0,0,2,3,4,5,12\r\n", "Australia (AUS) [AUS] [Z],25,139,152,177,468,18,5,3,4,12,43,144,155,181,480\r\n", "Austria (AUT),26,18,33,35,86,22,59,78,81,218,48,77,111,116,304\r\n", "Azerbaijan (AZE),5,6,5,15,26,5,0,0,0,0,10,6,5,15,26\r\n", "Bahamas (BAH),15,5,2,5,12,0,0,0,0,0,15,5,2,5,12\r\n", "Bahrain (BRN),8,0,0,1,1,0,0,0,0,0,8,0,0,1,1\r\n", "Barbados (BAR) [BAR],11,0,0,1,1,0,0,0,0,0,11,0,0,1,1\r\n", "Belarus (BLR),5,12,24,39,75,6,6,4,5,15,11,18,28,44,90\r\n", "Belgium (BEL),25,37,52,53,142,20,1,1,3,5,45,38,53,56,147\r\n", "Bermuda (BER),17,0,0,1,1,7,0,0,0,0,24,0,0,1,1\r\n", "Bohemia (BOH) [BOH] [Z],3,0,1,3,4,0,0,0,0,0,3,0,1,3,4\r\n", "Botswana (BOT),9,0,1,0,1,0,0,0,0,0,9,0,1,0,1\r\n", "Brazil (BRA),21,23,30,55,108,7,0,0,0,0,28,23,30,55,108\r\n", "British West Indies (BWI) [BWI],1,0,0,2,2,0,0,0,0,0,1,0,0,2,2\r\n", "Bulgaria (BUL) [H],19,51,85,78,214,19,1,2,3,6,38,52,87,81,220\r\n", "Burundi (BDI),5,1,0,0,1,0,0,0,0,0,5,1,0,0,1\r\n", "Cameroon (CMR),13,3,1,1,5,1,0,0,0,0,14,3,1,1,5\r\n", "Canada (CAN),25,59,99,121,279,22,62,56,52,170,47,121,155,173,449\r\n", "Chile (CHI) [I],22,2,7,4,13,16,0,0,0,0,38,2,7,4,13\r\n", "China (CHN) [CHN],9,201,146,126,473,10,12,22,19,53,19,213,168,145,526\r\n", "Colombia (COL),18,2,6,11,19,1,0,0,0,0,19,2,6,11,19\r\n", "Costa Rica (CRC),14,1,1,2,4,6,0,0,0,0,20,1,1,2,4\r\n", "Ivory Coast (CIV) [CIV],12,0,1,0,1,0,0,0,0,0,12,0,1,0,1\r\n", "Croatia (CRO),6,6,7,10,23,7,4,6,1,11,13,10,13,11,34\r\n", "Cuba (CUB) [Z],19,72,67,70,209,0,0,0,0,0,19,72,67,70,209\r\n", "Cyprus (CYP),9,0,1,0,1,10,0,0,0,0,19,0,1,0,1\r\n", "Czech Republic (CZE) [CZE],5,14,15,15,44,6,7,9,8,24,11,21,24,23,68\r\n", "Czechoslovakia (TCH) [TCH],16,49,49,45,143,16,2,8,15,25,32,51,57,60,168\r\n", "Denmark (DEN) [Z],26,43,68,68,179,13,0,1,0,1,39,43,69,68,180\r\n", "Djibouti (DJI) [B],7,0,0,1,1,0,0,0,0,0,7,0,0,1,1\r\n", "Dominican Republic (DOM),13,3,2,1,6,0,0,0,0,0,13,3,2,1,6\r\n", "Ecuador (ECU),13,1,1,0,2,0,0,0,0,0,13,1,1,0,2\r\n", "Egypt (EGY) [EGY] [Z],21,7,9,10,26,1,0,0,0,0,22,7,9,10,26\r\n", "Eritrea (ERI),4,0,0,1,1,0,0,0,0,0,4,0,0,1,1\r\n", "Estonia (EST),11,9,9,15,33,9,4,2,1,7,20,13,11,16,40\r\n", "Ethiopia (ETH),12,21,7,17,45,2,0,0,0,0,14,21,7,17,45\r\n", "Finland (FIN),24,101,84,117,302,22,42,62,57,161,46,143,146,174,463\r\n", "France (FRA) [O] [P] [Z],27,202,223,246,671,22,31,31,47,109,49,233,254,293,780\r\n", "Gabon (GAB),9,0,1,0,1,0,0,0,0,0,9,0,1,0,1\r\n", "Georgia (GEO),5,6,5,14,25,6,0,0,0,0,11,6,5,14,25\r\n", "Germany (GER) [GER] [Z],15,174,182,217,573,11,78,78,53,209,26,252,260,270,782\r\n", "United Team of Germany (EUA) [EUA],3,28,54,36,118,3,8,6,5,19,6,36,60,41,137\r\n", "East Germany (GDR) [GDR],5,153,129,127,409,6,39,36,35,110,11,192,165,162,519\r\n", "West Germany (FRG) [FRG],5,56,67,81,204,6,11,15,13,39,11,67,82,94,243\r\n", "Ghana (GHA) [GHA],13,0,1,3,4,1,0,0,0,0,14,0,1,3,4\r\n", "Great Britain (GBR) [GBR] [Z],27,236,272,272,780,22,10,4,12,26,49,246,276,284,806\r\n", "Greece (GRE) [Z],27,30,42,39,111,18,0,0,0,0,45,30,42,39,111\r\n", "Grenada (GRN),8,1,0,0,1,0,0,0,0,0,8,1,0,0,1\r\n", "Guatemala (GUA),13,0,1,0,1,1,0,0,0,0,14,0,1,0,1\r\n", "Guyana (GUY) [GUY],16,0,0,1,1,0,0,0,0,0,16,0,0,1,1\r\n", "Haiti (HAI) [J],14,0,1,1,2,0,0,0,0,0,14,0,1,1,2\r\n", "Hong Kong (HKG) [HKG],15,1,1,1,3,4,0,0,0,0,19,1,1,1,3\r\n", "Hungary (HUN),25,167,144,165,476,22,0,2,4,6,47,167,146,169,482\r\n", "Iceland (ISL),19,0,2,2,4,17,0,0,0,0,36,0,2,2,4\r\n", "India (IND) [F],23,9,6,11,26,9,0,0,0,0,32,9,6,11,26\r\n", "Indonesia (INA),14,6,10,11,27,0,0,0,0,0,14,6,10,11,27\r\n", "Iran (IRI) [K],15,15,20,25,60,10,0,0,0,0,25,15,20,25,60\r\n", "Iraq (IRQ),13,0,0,1,1,0,0,0,0,0,13,0,0,1,1\r\n", "Ireland (IRL),20,9,8,12,29,6,0,0,0,0,26,9,8,12,29\r\n", "Israel (ISR),15,1,1,5,7,6,0,0,0,0,21,1,1,5,7\r\n", "Italy (ITA) [M] [S],26,198,166,185,549,22,37,34,43,114,48,235,200,228,663\r\n", "Jamaica (JAM) [JAM],16,17,30,20,67,7,0,0,0,0,23,17,30,20,67\r\n", "Japan (JPN),21,130,126,142,398,20,10,17,18,45,41,140,143,160,443\r\n", "Kazakhstan (KAZ),5,16,17,19,52,6,1,3,3,7,11,17,20,22,59\r\n", "Kenya (KEN),13,25,32,29,86,3,0,0,0,0,16,25,32,29,86\r\n", "North Korea (PRK),9,14,12,21,47,8,0,1,1,2,17,14,13,22,49\r\n", "South Korea (KOR),16,81,82,80,243,17,26,17,10,53,33,107,99,90,296\r\n", "Kuwait (KUW),12,0,0,2,2,0,0,0,0,0,12,0,0,2,2\r\n", "Kyrgyzstan (KGZ),5,0,1,2,3,6,0,0,0,0,11,0,1,2,3\r\n", "Latvia (LAT),10,3,11,5,19,10,0,4,3,7,20,3,15,8,26\r\n", "Lebanon (LIB),16,0,2,2,4,16,0,0,0,0,32,0,2,2,4\r\n", "Liechtenstein (LIE),16,0,0,0,0,18,2,2,5,9,34,2,2,5,9\r\n", "Lithuania (LTU),8,6,5,10,21,8,0,0,0,0,16,6,5,10,21\r\n", "Luxembourg (LUX) [O],22,1,1,0,2,8,0,2,0,2,30,1,3,0,4\r\n", "Macedonia (MKD),5,0,0,1,1,5,0,0,0,0,10,0,0,1,1\r\n", "Malaysia (MAS) [MAS],12,0,3,3,6,0,0,0,0,0,12,0,3,3,6\r\n", "Mauritius (MRI),8,0,0,1,1,0,0,0,0,0,8,0,0,1,1\r\n", "Mexico (MEX),22,13,21,28,62,8,0,0,0,0,30,13,21,28,62\r\n", "Moldova (MDA),5,0,2,5,7,6,0,0,0,0,11,0,2,5,7\r\n", "Mongolia (MGL),12,2,9,13,24,13,0,0,0,0,25,2,9,13,24\r\n", "Montenegro (MNE),2,0,1,0,1,2,0,0,0,0,4,0,1,0,1\r\n", "Morocco (MAR),13,6,5,11,22,6,0,0,0,0,19,6,5,11,22\r\n", "Mozambique (MOZ),9,1,0,1,2,0,0,0,0,0,9,1,0,1,2\r\n", "Namibia (NAM),6,0,4,0,4,0,0,0,0,0,6,0,4,0,4\r\n", "Netherlands (NED) [Z],25,77,85,104,266,20,37,38,35,110,45,114,123,139,376\r\n", "Netherlands Antilles (AHO) [AHO] [I],13,0,1,0,1,2,0,0,0,0,15,0,1,0,1\r\n", "New Zealand (NZL) [NZL],22,42,18,39,99,15,0,1,0,1,37,42,19,39,100\r\n", "Niger (NIG),11,0,0,1,1,0,0,0,0,0,11,0,0,1,1\r\n", "Nigeria (NGR),15,3,8,12,23,0,0,0,0,0,15,3,8,12,23\r\n", "Norway (NOR) [Q],24,56,49,43,148,22,118,111,100,329,46,174,160,143,477\r\n", "Pakistan (PAK),16,3,3,4,10,2,0,0,0,0,18,3,3,4,10\r\n", "Panama (PAN),16,1,0,2,3,0,0,0,0,0,16,1,0,2,3\r\n", "Paraguay (PAR),11,0,1,0,1,1,0,0,0,0,12,0,1,0,1\r\n", "Peru (PER) [L],17,1,3,0,4,2,0,0,0,0,19,1,3,0,4\r\n", "Philippines (PHI),20,0,2,7,9,4,0,0,0,0,24,0,2,7,9\r\n", "Poland (POL),20,64,82,125,271,22,6,7,7,20,42,70,89,132,291\r\n", "Portugal (POR),23,4,8,11,23,7,0,0,0,0,30,4,8,11,23\r\n", "Puerto Rico (PUR),17,0,2,6,8,6,0,0,0,0,23,0,2,6,8\r\n", "Qatar (QAT),8,0,0,4,4,0,0,0,0,0,8,0,0,4,4\r\n", "Romania (ROU),20,88,94,119,301,20,0,0,1,1,40,88,94,120,302\r\n", "Russia (RUS) [RUS],5,132,121,142,395,6,49,40,35,124,11,181,161,177,519\r\n", "Russian Empire (RU1) [RU1],3,1,4,3,8,0,0,0,0,0,3,1,4,3,8\r\n", "Soviet Union (URS) [URS],9,395,319,296,1010,9,78,57,59,194,18,473,376,355,1204\r\n", "Unified Team (EUN) [EUN],1,45,38,29,112,1,9,6,8,23,2,54,44,37,135\r\n", "Saudi Arabia (KSA),10,0,1,2,3,0,0,0,0,0,10,0,1,2,3\r\n", "Senegal (SEN),13,0,1,0,1,5,0,0,0,0,18,0,1,0,1\r\n", "Serbia (SRB) [SRB],3,1,2,4,7,2,0,0,0,0,5,1,2,4,7\r\n", "Serbia and Montenegro (SCG) [SCG],3,2,4,3,9,3,0,0,0,0,6,2,4,3,9\r\n", "Singapore (SIN),15,0,2,2,4,0,0,0,0,0,15,0,2,2,4\r\n", "Slovakia (SVK) [SVK],5,7,9,8,24,6,2,2,1,5,11,9,11,9,29\r\n", "Slovenia (SLO),6,4,6,9,19,7,2,4,9,15,13,6,10,18,34\r\n", "South Africa (RSA),18,23,26,27,76,6,0,0,0,0,24,23,26,27,76\r\n", "Spain (ESP) [Z],22,37,59,35,131,19,1,0,1,2,41,38,59,36,133\r\n", "Sri Lanka (SRI) [SRI],16,0,2,0,2,0,0,0,0,0,16,0,2,0,2\r\n", "Sudan (SUD),11,0,1,0,1,0,0,0,0,0,11,0,1,0,1\r\n", "Suriname (SUR) [E],11,1,0,1,2,0,0,0,0,0,11,1,0,1,2\r\n", "Sweden (SWE) [Z],26,143,164,176,483,22,50,40,54,144,48,193,204,230,627\r\n", "Switzerland (SUI),27,47,73,65,185,22,50,40,48,138,49,97,113,113,323\r\n", "Syria (SYR),12,1,1,1,3,0,0,0,0,0,12,1,1,1,3\r\n", "Chinese Taipei (TPE) [TPE] [TPE2],13,2,7,12,21,11,0,0,0,0,24,2,7,12,21\r\n", "Tajikistan (TJK),5,0,1,2,3,4,0,0,0,0,9,0,1,2,3\r\n", "Tanzania (TAN) [TAN],12,0,2,0,2,0,0,0,0,0,12,0,2,0,2\r\n", "Thailand (THA),15,7,6,11,24,3,0,0,0,0,18,7,6,11,24\r\n", "Togo (TOG),9,0,0,1,1,1,0,0,0,0,10,0,0,1,1\r\n", "Tonga (TGA),8,0,1,0,1,1,0,0,0,0,9,0,1,0,1\r\n", "Trinidad and Tobago (TRI) [TRI],16,2,5,11,18,3,0,0,0,0,19,2,5,11,18\r\n", "Tunisia (TUN),13,3,3,4,10,0,0,0,0,0,13,3,3,4,10\r\n", "Turkey (TUR),21,39,25,24,88,16,0,0,0,0,37,39,25,24,88\r\n", "Uganda (UGA),14,2,3,2,7,0,0,0,0,0,14,2,3,2,7\r\n", "Ukraine (UKR),5,33,27,55,115,6,2,1,4,7,11,35,28,59,122\r\n", "United Arab Emirates (UAE),8,1,0,0,1,0,0,0,0,0,8,1,0,0,1\r\n", "United States (USA) [P] [Q] [R] [Z],26,976,757,666,2399,22,96,102,84,282,48,1072,859,750,2681\r\n", "Uruguay (URU),20,2,2,6,10,1,0,0,0,0,21,2,2,6,10\r\n", "Uzbekistan (UZB),5,5,5,10,20,6,1,0,0,1,11,6,5,10,21\r\n", "Venezuela (VEN),17,2,2,8,12,4,0,0,0,0,21,2,2,8,12\r\n", "Vietnam (VIE),14,0,2,0,2,0,0,0,0,0,14,0,2,0,2\r\n", "Virgin Islands (ISV),11,0,1,0,1,7,0,0,0,0,18,0,1,0,1\r\n", "Yugoslavia (YUG) [YUG],16,26,29,28,83,14,0,3,1,4,30,26,32,29,87\r\n", "Independent Olympic Participants (IOP) [IOP],1,0,1,2,3,0,0,0,0,0,1,0,1,2,3\r\n", "Zambia (ZAM) [ZAM],12,0,1,1,2,0,0,0,0,0,12,0,1,1,2\r\n", "Zimbabwe (ZIM) [ZIM],12,3,4,1,8,1,0,0,0,0,13,3,4,1,8\r\n", "Mixed team (ZZX) [ZZX],3,8,5,4,17,0,0,0,0,0,3,8,5,4,17\r\n", "Totals,27,4809,4775,5130,14714,22,959,958,948,2865,49,5768,5733,6078,17579\r\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "hola\r\n" ] } ], "source": [ "!cat olympics.csv" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Pero ... no hay que preocuparse mucho por eso! Podemos leer este archivo en formato `CSV` en un `DataFrame` usando la función `read_csv`. " ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/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", "
0123456789101112131415
0NaN№ Summer01 !02 !03 !Total№ Winter01 !02 !03 !Total№ Games01 !02 !03 !Combined total
1Afghanistan (AFG)13002200000130022
2Algeria (ALG)1252815300001552815
3Argentina (ARG)23182428701800004118242870
4Armenia (ARM)512912600001112912
\n", "
" ], "text/plain": [ " 0 1 2 3 4 5 6 7 8 \\\n", "0 NaN № Summer 01 ! 02 ! 03 ! Total № Winter 01 ! 02 ! \n", "1 Afghanistan (AFG) 13 0 0 2 2 0 0 0 \n", "2 Algeria (ALG) 12 5 2 8 15 3 0 0 \n", "3 Argentina (ARG) 23 18 24 28 70 18 0 0 \n", "4 Armenia (ARM) 5 1 2 9 12 6 0 0 \n", "\n", " 9 10 11 12 13 14 15 \n", "0 03 ! Total № Games 01 ! 02 ! 03 ! Combined total \n", "1 0 0 13 0 0 2 2 \n", "2 0 0 15 5 2 8 15 \n", "3 0 0 41 18 24 28 70 \n", "4 0 0 11 1 2 9 12 " ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import pandas as pd\n", "df = pd.read_csv('olympics.csv')\n", "df.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Aquí podemos ignorar la primera fila del `DataFrame` para dejar más limpia la tabla de información no relevante." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/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", "
№ Summer01 !02 !03 !Total№ Winter01 !.102 !.103 !.1Total.1№ Games01 !.202 !.203 !.2Combined total
Afghanistan (AFG)13002200000130022
Algeria (ALG)1252815300001552815
Argentina (ARG)23182428701800004118242870
Armenia (ARM)512912600001112912
Australasia (ANZ) [ANZ]23451200000234512
\n", "
" ], "text/plain": [ " № Summer 01 ! 02 ! 03 ! Total № Winter 01 !.1 \\\n", "Afghanistan (AFG) 13 0 0 2 2 0 0 \n", "Algeria (ALG) 12 5 2 8 15 3 0 \n", "Argentina (ARG) 23 18 24 28 70 18 0 \n", "Armenia (ARM) 5 1 2 9 12 6 0 \n", "Australasia (ANZ) [ANZ] 2 3 4 5 12 0 0 \n", "\n", " 02 !.1 03 !.1 Total.1 № Games 01 !.2 02 !.2 \\\n", "Afghanistan (AFG) 0 0 0 13 0 0 \n", "Algeria (ALG) 0 0 0 15 5 2 \n", "Argentina (ARG) 0 0 0 41 18 24 \n", "Armenia (ARM) 0 0 0 11 1 2 \n", "Australasia (ANZ) [ANZ] 0 0 0 2 3 4 \n", "\n", " 03 !.2 Combined total \n", "Afghanistan (AFG) 2 2 \n", "Algeria (ALG) 8 15 \n", "Argentina (ARG) 28 70 \n", "Armenia (ARM) 9 12 \n", "Australasia (ANZ) [ANZ] 5 12 " ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df = pd.read_csv('olympics.csv', index_col = 0, skiprows=1)\n", "df.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "El atributo `.columns` nos permite ver el nombre de las comlumnas del `DataFrame` y el atributo `.rename` modificar el nombre." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Index(['№ Summer', '01 !', '02 !', '03 !', 'Total', '№ Winter', '01 !.1',\n", " '02 !.1', '03 !.1', 'Total.1', '№ Games', '01 !.2', '02 !.2', '03 !.2',\n", " 'Combined total'],\n", " dtype='object')" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.columns" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/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", "
# SummerGoldSilverBronzeTotal# WinterGold.1Silver.1Bronze.1Total.1# GamesGold.2Silver.2Bronze.2Combined total
Afghanistan (AFG)13002200000130022
Algeria (ALG)1252815300001552815
Argentina (ARG)23182428701800004118242870
Armenia (ARM)512912600001112912
Australasia (ANZ) [ANZ]23451200000234512
\n", "
" ], "text/plain": [ " # Summer Gold Silver Bronze Total # Winter \\\n", "Afghanistan (AFG) 13 0 0 2 2 0 \n", "Algeria (ALG) 12 5 2 8 15 3 \n", "Argentina (ARG) 23 18 24 28 70 18 \n", "Armenia (ARM) 5 1 2 9 12 6 \n", "Australasia (ANZ) [ANZ] 2 3 4 5 12 0 \n", "\n", " Gold.1 Silver.1 Bronze.1 Total.1 # Games Gold.2 \\\n", "Afghanistan (AFG) 0 0 0 0 13 0 \n", "Algeria (ALG) 0 0 0 0 15 5 \n", "Argentina (ARG) 0 0 0 0 41 18 \n", "Armenia (ARM) 0 0 0 0 11 1 \n", "Australasia (ANZ) [ANZ] 0 0 0 0 2 3 \n", "\n", " Silver.2 Bronze.2 Combined total \n", "Afghanistan (AFG) 0 2 2 \n", "Algeria (ALG) 2 8 15 \n", "Argentina (ARG) 24 28 70 \n", "Armenia (ARM) 2 9 12 \n", "Australasia (ANZ) [ANZ] 4 5 12 " ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "for col in df.columns:\n", " if col[:2]=='01':\n", " df.rename(columns={col:'Gold' + col[4:]}, inplace=True)\n", " if col[:2]=='02':\n", " df.rename(columns={col:'Silver' + col[4:]}, inplace=True)\n", " if col[:2]=='03':\n", " df.rename(columns={col:'Bronze' + col[4:]}, inplace=True)\n", " if col[:1]=='№':\n", " df.rename(columns={col:'#' + col[1:]}, inplace=True) \n", "\n", "df.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Haciendo búsquedas en un `DataFrame`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Podemos buscar en el `DataFrame` con una **máscara Booleana** qué países tienen (`True`) o no (`False`) una medalla de oro." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Afghanistan (AFG) False\n", "Algeria (ALG) True\n", "Argentina (ARG) True\n", "Armenia (ARM) True\n", "Australasia (ANZ) [ANZ] True\n", "Australia (AUS) [AUS] [Z] True\n", "Austria (AUT) True\n", "Azerbaijan (AZE) True\n", "Bahamas (BAH) True\n", "Bahrain (BRN) False\n", "Barbados (BAR) [BAR] False\n", "Belarus (BLR) True\n", "Belgium (BEL) True\n", "Bermuda (BER) False\n", "Bohemia (BOH) [BOH] [Z] False\n", "Botswana (BOT) False\n", "Brazil (BRA) True\n", "British West Indies (BWI) [BWI] False\n", "Bulgaria (BUL) [H] True\n", "Burundi (BDI) True\n", "Cameroon (CMR) True\n", "Canada (CAN) True\n", "Chile (CHI) [I] True\n", "China (CHN) [CHN] True\n", "Colombia (COL) True\n", "Costa Rica (CRC) True\n", "Ivory Coast (CIV) [CIV] False\n", "Croatia (CRO) True\n", "Cuba (CUB) [Z] True\n", "Cyprus (CYP) False\n", " ... \n", "Sri Lanka (SRI) [SRI] False\n", "Sudan (SUD) False\n", "Suriname (SUR) [E] True\n", "Sweden (SWE) [Z] True\n", "Switzerland (SUI) True\n", "Syria (SYR) True\n", "Chinese Taipei (TPE) [TPE] [TPE2] True\n", "Tajikistan (TJK) False\n", "Tanzania (TAN) [TAN] False\n", "Thailand (THA) True\n", "Togo (TOG) False\n", "Tonga (TGA) False\n", "Trinidad and Tobago (TRI) [TRI] True\n", "Tunisia (TUN) True\n", "Turkey (TUR) True\n", "Uganda (UGA) True\n", "Ukraine (UKR) True\n", "United Arab Emirates (UAE) True\n", "United States (USA) [P] [Q] [R] [Z] True\n", "Uruguay (URU) True\n", "Uzbekistan (UZB) True\n", "Venezuela (VEN) True\n", "Vietnam (VIE) False\n", "Virgin Islands (ISV) False\n", "Yugoslavia (YUG) [YUG] True\n", "Independent Olympic Participants (IOP) [IOP] False\n", "Zambia (ZAM) [ZAM] False\n", "Zimbabwe (ZIM) [ZIM] True\n", "Mixed team (ZZX) [ZZX] True\n", "Totals True\n", "Name: Gold, Length: 147, dtype: bool" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df['Gold'] > 0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "La función `.where()` toma una máscara booleana como condición en el argumento, la aplica al `DataFrame`, y devuelve un `DataFrame` de la misma forma. En nuestro ejemplo, reemplaza con `NaN` los casos `False` y con su valor original, los casos `True`." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/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", "
# SummerGoldSilverBronzeTotal# WinterGold.1Silver.1Bronze.1Total.1# GamesGold.2Silver.2Bronze.2Combined total
Afghanistan (AFG)NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
Algeria (ALG)12.05.02.08.015.03.00.00.00.00.015.05.02.08.015.0
Argentina (ARG)23.018.024.028.070.018.00.00.00.00.041.018.024.028.070.0
Armenia (ARM)5.01.02.09.012.06.00.00.00.00.011.01.02.09.012.0
Australasia (ANZ) [ANZ]2.03.04.05.012.00.00.00.00.00.02.03.04.05.012.0
\n", "
" ], "text/plain": [ " # Summer Gold Silver Bronze Total # Winter \\\n", "Afghanistan (AFG) NaN NaN NaN NaN NaN NaN \n", "Algeria (ALG) 12.0 5.0 2.0 8.0 15.0 3.0 \n", "Argentina (ARG) 23.0 18.0 24.0 28.0 70.0 18.0 \n", "Armenia (ARM) 5.0 1.0 2.0 9.0 12.0 6.0 \n", "Australasia (ANZ) [ANZ] 2.0 3.0 4.0 5.0 12.0 0.0 \n", "\n", " Gold.1 Silver.1 Bronze.1 Total.1 # Games Gold.2 \\\n", "Afghanistan (AFG) NaN NaN NaN NaN NaN NaN \n", "Algeria (ALG) 0.0 0.0 0.0 0.0 15.0 5.0 \n", "Argentina (ARG) 0.0 0.0 0.0 0.0 41.0 18.0 \n", "Armenia (ARM) 0.0 0.0 0.0 0.0 11.0 1.0 \n", "Australasia (ANZ) [ANZ] 0.0 0.0 0.0 0.0 2.0 3.0 \n", "\n", " Silver.2 Bronze.2 Combined total \n", "Afghanistan (AFG) NaN NaN NaN \n", "Algeria (ALG) 2.0 8.0 15.0 \n", "Argentina (ARG) 24.0 28.0 70.0 \n", "Armenia (ARM) 2.0 9.0 12.0 \n", "Australasia (ANZ) [ANZ] 4.0 5.0 12.0 " ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "only_gold = df.where(df['Gold'] > 0)\n", "only_gold.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Podemos contar cuántas países hay medallas de oro hay en total con `count()`" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "100" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "only_gold['Gold'].count()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Si contamos sobre los datos originales, veremos que hay 147 países. Cuenta los países para los cuales la máscara Booleana dio `False` >.<" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "147" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df['Gold'].count()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Podemos establecer otro tipo de condiciones para hacer búsquedas más complejas. Por ejemplo, buscar la cantidad de países que han ganado medalla de oro alguna vez." ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "101" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(df[(df['Gold'] > 0) | (df['Gold.1'] > 0)])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Buscar qué países han ganado sólo medallas de oro en Invierno y nunca en Verano." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/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", "
# SummerGoldSilverBronzeTotal# WinterGold.1Silver.1Bronze.1Total.1# GamesGold.2Silver.2Bronze.2Combined total
Liechtenstein (LIE)160000182259342259
\n", "
" ], "text/plain": [ " # Summer Gold Silver Bronze Total # Winter Gold.1 \\\n", "Liechtenstein (LIE) 16 0 0 0 0 18 2 \n", "\n", " Silver.1 Bronze.1 Total.1 # Games Gold.2 Silver.2 \\\n", "Liechtenstein (LIE) 2 5 9 34 2 2 \n", "\n", " Bronze.2 Combined total \n", "Liechtenstein (LIE) 5 9 " ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df[(df['Gold.1'] > 0) & (df['Gold'] == 0)]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.4" } }, "nbformat": 4, "nbformat_minor": 1 }