In [0]:
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
Objetivos de aprendizaje:
DataFrame
y Series
de la biblioteca de PandasDataFrame
y Series
DataFrame
de PandasDataFrame
para obtener datos aleatoriospandas es una API de análisis de datos en columnas, ideal para manipular y analizar datos de entrada. Además, muchos marcos de trabajo de AA admiten las estructuras de datos pandas como entradas. Si bien una introducción detallada a la API de pandas abarcaría muchas páginas, los conceptos principales que presentamos a continuación son simples. Para obtener una referencia más completa, el sitio de documentación de pandas incluye una documentación exhaustiva y numerosos instructivos.
In [0]:
from __future__ import print_function
import pandas as pd
pd.__version__
Las estructuras de datos principales en pandas están implementadas en dos clases:
DataFrame
, que puedes imaginar como una tabla de datos relacional, con filas y columnas con nombre.Series
, que es una columna simple. Una clase DataFrame
incluye una o más Series
y un nombre para cada Series
.El marco de datos es una abstracción que se usa normalmente para manipular datos. Hay implementaciones similares en Spark y R.
Una manera de crear una Series
es construir un objeto de Series
. Por ejemplo:
In [0]:
pd.Series(['San Francisco', 'San Jose', 'Sacramento'])
Los objetos de DataFrame
pueden crearse al enviar un dict
que asigne nombres de columnas de string
a sus Series
correspondientes. Si las Series
no coinciden con la longitud, los valores que falten se completan con valores NA/NaN especiales. Ejemplo:
In [0]:
city_names = pd.Series(['San Francisco', 'San Jose', 'Sacramento'])
population = pd.Series([852469, 1015785, 485199])
pd.DataFrame({ 'City name': city_names, 'Population': population })
Pero por lo general, cargas un archivo completo en un DataFrame
. El siguiente ejemplo carga un archivo con datos de viviendas de California. Ejecuta la siguiente celda para cargar los datos y crear definiciones de funciones:
In [0]:
california_housing_dataframe = pd.read_csv("https://download.mlcc.google.com/mledu-datasets/california_housing_train.csv", sep=",")
california_housing_dataframe.describe()
En el ejemplo de arriba, se usó DataFrame.describe
para mostrar estadísticas interesantes sobre un DataFrame
. Otra función útil es DataFrame.head
, que muestra los primeros registros de un DataFrame
:
In [0]:
california_housing_dataframe.head()
Otra función util de pandas es la generación de gráficos. Por ejemplo, DataFrame.hist
permite estudiar rápidamente la distribución de los valores en una columna:
In [0]:
california_housing_dataframe.hist('housing_median_age')
In [0]:
cities = pd.DataFrame({ 'City name': city_names, 'Population': population })
print(type(cities['City name']))
cities['City name']
In [0]:
print(type(cities['City name'][1]))
cities['City name'][1]
In [0]:
print(type(cities[0:2]))
cities[0:2]
Además, pandas proporciona una API muy enriquecida para una indexación y selección avanzadas, que es un tema demasiado amplio como para cubrirlo aquí.
In [0]:
population / 1000.
NumPy es un kit de herramientas popular para el cálculo científico. Las Series
de pandas pueden usarse como argumentos para la mayoría de las funciones NumPy:
In [0]:
import numpy as np
np.log(population)
Para obtener información sobre transformaciones más complejas de una sola columna, puedes usar Series.apply
. Al igual que la función función map de Python, Series.apply
acepta como argumento una función función lambda, que se aplica a cada valor.
El siguiente ejemplo crea una nueva Series
que indica si la population
es superior a un millón:
In [0]:
population.apply(lambda val: val > 1000000)
Modificar DataFrames
también es simple. Por ejemplo, el siguiente código agrega dos Series
a un DataFrame
existente:
In [0]:
cities['Area square miles'] = pd.Series([46.87, 176.53, 97.92])
cities['Population density'] = cities['Population'] / cities['Area square miles']
cities
Para modificar la tabla de cities
, agrega una nueva columna booleana que sea Verdadera si y solo si ambos de los siguientes valores son Verdaderos:
Nota: Las Series
booleanas se combinan en función de los bits, en lugar de los operadores booleanos tradicionales. Por ejemplo, cuando utilices logical and, usa &
en lugar de and
.
Hint: "San" en español representa "santo".
In [0]:
# Your code here
In [0]:
cities['Is wide and has saint name'] = (cities['Area square miles'] > 50) & cities['City name'].apply(lambda name: name.startswith('San'))
cities
Los objetos Series
y DataFrame
también definen una propiedad de index
que asigna un valor de identificador a cada elemento Series
o fila DataFrame
.
De forma predeterminada, en la construcción, pandas asigna valores de índice que reflejan la solicitud de los datos de origen. Una vez creados, los valores de índice son estables, es decir, no cambian cuando cambia el orden de los datos.
In [0]:
city_names.index
In [0]:
cities.index
Llama DataFrame.reindex
para cambiar el orden de las filas de forma manual. Por ejemplo, la siguiente acción tiene el mismo efecto que ordenar los valores por nombre de ciudad:
In [0]:
cities.reindex([2, 0, 1])
La reindexación es una excelente manera de seleccionar un DataFrame
de forma aleatoria. En el ejemplo que se muestra a continuación, tomamos el índice, que es del tipo matriz, y lo enviamos a la función random.permutation
de NumPy, que selecciona sus valores de forma aleatoria. Utilizar la reindexación
con esta matriz aleatoria provoca que las filas de DataFrame
se seleccionen de forma aleatoria de la misma manera.
¡Prueba ejecutar la siguiente celda varias veces!
In [0]:
cities.reindex(np.random.permutation(cities.index))
Para obtener más información, consulta Documentación de índice.
In [0]:
# Your code here
Si la matriz de la entrada reindex
incluye valores que no se encuentran en los valores de índice originales DataFrame
, reindex
agregará nuevas filas para esos índices "faltantes" y completará todas las columnas correspondientes con los valores NaN
:
In [0]:
cities.reindex([0, 4, 5, 2])
Este comportamiento es util, ya que por lo general los índices son strings extraídos de los datos actuales (consulta la pandas reindex documentation para obtener un ejemplo en el que los valores de índice son nombres de navegadores).
En este caso, permitir los índices "faltantes" facilita la reindexación mediante una lista externa, dado que no tienes que preocuparte por sanear directamente las entradas.