Varios problemas de análisis de datos

PythonPythonBeginner
Practicar Ahora

This tutorial is from open-source community. Access the source code

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este laboratorio, aprenderás a trabajar con varios contenedores de datos de Python y a utilizar comprensiones de listas, conjuntos y diccionarios. También explorarás el módulo collections, que proporciona herramientas útiles para el manejo de datos.

Python ofrece herramientas poderosas para la manipulación y análisis de datos. En este laboratorio, practicarás el uso de las estructuras de datos integradas de Python y herramientas especializadas para analizar diferentes conjuntos de datos. Comenzando con un simple conjunto de datos de cartera, avanzarás hacia el análisis de los datos de autobuses de la Autoridad de Transporte de Chicago (Chicago Transit Authority) para extraer información significativa.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL python(("Python")) -.-> python/DataStructuresGroup(["Data Structures"]) python(("Python")) -.-> python/FileHandlingGroup(["File Handling"]) python(("Python")) -.-> python/PythonStandardLibraryGroup(["Python Standard Library"]) python(("Python")) -.-> python/DataScienceandMachineLearningGroup(["Data Science and Machine Learning"]) python(("Python")) -.-> python/ControlFlowGroup(["Control Flow"]) python/ControlFlowGroup -.-> python/list_comprehensions("List Comprehensions") python/DataStructuresGroup -.-> python/lists("Lists") python/DataStructuresGroup -.-> python/dictionaries("Dictionaries") python/DataStructuresGroup -.-> python/sets("Sets") python/FileHandlingGroup -.-> python/file_reading_writing("Reading and Writing Files") python/FileHandlingGroup -.-> python/file_operations("File Operations") python/PythonStandardLibraryGroup -.-> python/data_collections("Data Collections") python/DataScienceandMachineLearningGroup -.-> python/data_analysis("Data Analysis") subgraph Lab Skills python/list_comprehensions -.-> lab-132438{{"Varios problemas de análisis de datos"}} python/lists -.-> lab-132438{{"Varios problemas de análisis de datos"}} python/dictionaries -.-> lab-132438{{"Varios problemas de análisis de datos"}} python/sets -.-> lab-132438{{"Varios problemas de análisis de datos"}} python/file_reading_writing -.-> lab-132438{{"Varios problemas de análisis de datos"}} python/file_operations -.-> lab-132438{{"Varios problemas de análisis de datos"}} python/data_collections -.-> lab-132438{{"Varios problemas de análisis de datos"}} python/data_analysis -.-> lab-132438{{"Varios problemas de análisis de datos"}} end

Trabajando con Diccionarios y Datos CSV

Comencemos examinando un simple conjunto de datos sobre carteras de acciones. En este paso, aprenderás cómo leer datos de un archivo CSV y almacenarlos en un formato estructurado utilizando diccionarios.

Un archivo CSV (Comma-Separated Values, Valores Separados por Comas) es una forma común de almacenar datos tabulares, donde cada línea representa una fila y los valores están separados por comas. Los diccionarios en Python son una poderosa estructura de datos que te permite almacenar pares clave - valor. Al utilizar diccionarios, podemos organizar los datos del archivo CSV de una manera más significativa.

Primero, crea un nuevo archivo de Python en el WebIDE siguiendo estos pasos:

  1. Haz clic en el botón "Nuevo Archivo" en el WebIDE.
  2. Nombrar el archivo readport.py.
  3. Copia y pega el siguiente código en el archivo:
## readport.py

import csv

## A function that reads a file into a list of dictionaries
def read_portfolio(filename):
    portfolio = []
    with open(filename) as f:
        rows = csv.reader(f)
        headers = next(rows)   ## Skip the header row
        for row in rows:
            record = {
                'name': row[0],
                'shares': int(row[1]),
                'price': float(row[2])
            }
            portfolio.append(record)
    return portfolio

Este código define una función read_portfolio que realiza varias tareas importantes:

  1. Abre un archivo CSV especificado por el parámetro filename. La función open se utiliza para acceder al archivo, y la declaración with asegura que el archivo se cierre adecuadamente después de terminar de leerlo.
  2. Omite la fila de encabezado. La fila de encabezado generalmente contiene los nombres de las columnas en el archivo CSV. Usamos next(rows) para mover el iterador a la siguiente fila, saltando efectivamente el encabezado.
  3. Para cada fila de datos, crea un diccionario. Las claves del diccionario son 'name', 'shares' y 'price'. Estas claves nos ayudarán a acceder a los datos de una manera más intuitiva.
  4. Convierte las acciones en enteros y los precios en números de punto flotante. Esto es importante porque los datos leídos del archivo CSV están inicialmente en formato de cadena, y necesitamos valores numéricos para realizar cálculos.
  5. Agrega cada diccionario a una lista llamada portfolio. Esta lista contendrá todos los registros del archivo CSV.
  6. Finalmente, devuelve la lista completa de diccionarios.

Ahora, creemos un archivo para los datos de transporte público. Crea un nuevo archivo llamado readrides.py con este contenido:

## readrides.py

import csv

def read_rides_as_dicts(filename):
    """
    Read the CTA bus data as a list of dictionaries
    """
    records = []
    with open(filename) as f:
        rows = csv.reader(f)
        headers = next(rows)   ## Skip header
        for row in rows:
            route = row[0]
            date = row[1]
            daytype = row[2]
            rides = int(row[3])
            record = {
                'route': route,
                'date': date,
                'daytype': daytype,
                'rides': rides
            }
            records.append(record)
    return records

La función read_rides_as_dicts funciona de manera similar a la función read_portfolio. Lee un archivo CSV relacionado con los datos de autobuses de la CTA (Chicago Transit Authority), omite la fila de encabezado, crea un diccionario para cada fila de datos y almacena estos diccionarios en una lista.

Ahora, probemos la función read_portfolio abriendo un terminal en el WebIDE:

  1. Haz clic en el menú "Terminal" y selecciona "Nuevo Terminal".
  2. Inicia el intérprete de Python escribiendo python3.
  3. Ejecuta los siguientes comandos:
>>> from readport import read_portfolio
>>> portfolio = read_portfolio('/home/labex/project/portfolio.csv')
>>> from pprint import pprint
>>> pprint(portfolio)
[{'name': 'AA', 'price': 32.2, 'shares': 100},
 {'name': 'IBM', 'price': 91.1, 'shares': 50},
 {'name': 'CAT', 'price': 83.44, 'shares': 150},
 {'name': 'MSFT', 'price': 51.23, 'shares': 200},
 {'name': 'GE', 'price': 40.37, 'shares': 95},
 {'name': 'MSFT', 'price': 65.1, 'shares': 50},
 {'name': 'IBM', 'price': 70.44, 'shares': 100}]

La función pprint (impresión bonita) se utiliza aquí para mostrar los datos en un formato más legible. Cada elemento de la lista es un diccionario que representa una acción en la cartera. El diccionario tiene las siguientes claves:

  • Un símbolo de acción (name): Esta es la abreviatura utilizada para identificar la acción.
  • Número de acciones poseídas (shares): Esto indica cuántas acciones de la empresa se poseen.
  • Precio de compra por acción (price): Este es el precio al que se compró cada acción.

Observa que algunas acciones como 'MSFT' e 'IBM' aparecen varias veces. Estas representan diferentes compras de la misma acción, que podrían haberse realizado en diferentes momentos y precios.

✨ Revisar Solución y Practicar

Usando Comprensiones de Listas, Conjuntos y Diccionarios

Las comprensiones en Python son una forma realmente útil y concisa de crear nuevas colecciones basadas en otras existentes. Las colecciones en Python pueden ser listas, conjuntos o diccionarios, que son como contenedores que almacenan diferentes tipos de datos. Las comprensiones te permiten filtrar ciertos datos, transformarlos de alguna manera y organizarlos de forma más eficiente. En esta parte, usaremos nuestros datos de cartera para explorar cómo funcionan estas comprensiones.

Primero, necesitas abrir un terminal de Python, tal como lo hiciste en el paso anterior. Una vez abierto el terminal, ingresarás los siguientes ejemplos uno por uno. Este enfoque práctico te ayudará a entender cómo funcionan las comprensiones en la práctica.

Comprensiones de Listas

Una comprensión de lista es una sintaxis especial en Python que crea una nueva lista. Lo hace aplicando una expresión a cada elemento de una colección existente.

Comencemos con un ejemplo. Primero, importaremos una función para leer nuestros datos de cartera. Luego, usaremos una comprensión de lista para filtrar ciertas acciones de la cartera.

>>> from readport import read_portfolio
>>> portfolio = read_portfolio('/home/labex/project/portfolio.csv')

## Find all holdings with more than 100 shares
>>> large_holdings = [s for s in portfolio if s['shares'] > 100]
>>> print(large_holdings)
[{'name': 'CAT', 'shares': 150, 'price': 83.44}, {'name': 'MSFT', 'shares': 200, 'price': 51.23}]

En este código, primero importamos la función read_portfolio y la usamos para leer los datos de la cartera de un archivo CSV. Luego, la comprensión de lista [s for s in portfolio if s['shares'] > 100] recorre cada elemento s de la colección portfolio. Solo incluye el elemento s en la nueva lista large_holdings si el número de acciones de esa inversión es mayor a 100.

Las comprensiones de lista también se pueden usar para realizar cálculos. Aquí hay algunos ejemplos:

## Calculate the total cost of each holding (shares * price)
>>> holding_costs = [s['shares'] * s['price'] for s in portfolio]
>>> print(holding_costs)
[3220.0, 4555.0, 12516.0, 10246.0, 3835.15, 3255.0, 7044.0]

## Calculate the total cost of the entire portfolio
>>> total_portfolio_cost = sum([s['shares'] * s['price'] for s in portfolio])
>>> print(total_portfolio_cost)
44671.15

En el primer ejemplo, la comprensión de lista [s['shares'] * s['price'] for s in portfolio] calcula el costo total de cada inversión multiplicando el número de acciones por el precio de cada elemento en la portfolio. En el segundo ejemplo, usamos la función sum junto con la comprensión de lista para calcular el costo total de la cartera completa.

Comprensiones de Conjuntos

Una comprensión de conjunto se utiliza para crear un conjunto a partir de una colección existente. Un conjunto es una colección que solo contiene valores únicos.

Veamos cómo funciona con nuestros datos de cartera:

## Find all unique stock names
>>> unique_stocks = {s['name'] for s in portfolio}
>>> print(unique_stocks)
{'MSFT', 'IBM', 'AA', 'GE', 'CAT'}

En este código, la comprensión de conjunto {s['name'] for s in portfolio} recorre cada elemento s de la portfolio y agrega el nombre de la acción (s['name']) al conjunto unique_stocks. Dado que los conjuntos solo almacenan valores únicos, terminamos con una lista de todas las diferentes acciones en nuestra cartera sin duplicados.

Comprensiones de Diccionarios

Una comprensión de diccionario crea un nuevo diccionario aplicando expresiones para crear pares clave - valor.

Aquí hay un ejemplo de cómo usar una comprensión de diccionario para contar el número total de acciones de cada acción en nuestra cartera:

## Create a dictionary to count total shares for each stock
>>> totals = {s['name']: 0 for s in portfolio}
>>> for s in portfolio:
...     totals[s['name']] += s['shares']
...
>>> print(totals)
{'AA': 100, 'IBM': 150, 'CAT': 150, 'MSFT': 250, 'GE': 95}

En la primera línea, la comprensión de diccionario {s['name']: 0 for s in portfolio} crea un diccionario donde cada nombre de acción (s['name']) es una clave, y el valor inicial de cada clave es 0. Luego, usamos un bucle for para recorrer cada elemento de la portfolio. Para cada elemento, agregamos el número de acciones (s['shares']) al valor correspondiente en el diccionario totals.

Estas comprensiones son muy poderosas porque te permiten transformar y analizar datos con solo unas pocas líneas de código. Son una gran herramienta para tener en tu kit de herramientas de programación en Python.

Explorando el Módulo collections

En Python, los contenedores incorporados como listas, diccionarios y conjuntos son muy útiles. Sin embargo, el módulo collections de Python va un paso más allá al proporcionar tipos de datos de contenedores especializados que extienden la funcionalidad de estos contenedores incorporados. Echemos un vistazo más de cerca a algunos de estos tipos de datos útiles.

Continuarás trabajando en tu terminal de Python y seguirás los ejemplos a continuación.

Counter

La clase Counter es una subclase del diccionario. Su propósito principal es contar objetos hashables. Ofrece una forma conveniente de contar elementos y admite una variedad de operaciones.

Primero, necesitamos importar la clase Counter y una función para leer una cartera. Luego, leeremos una cartera desde un archivo CSV.

>>> from collections import Counter
>>> from readport import read_portfolio
>>> portfolio = read_portfolio('/home/labex/project/portfolio.csv')

Ahora, crearemos un objeto Counter para contar el número de acciones de cada acción por su nombre.

## Create a counter to count shares by stock name
>>> totals = Counter()
>>> for s in portfolio:
...     totals[s['name']] += s['shares']
...
>>> print(totals)
Counter({'MSFT': 250, 'IBM': 150, 'CAT': 150, 'AA': 100, 'GE': 95})

Una de las grandes características del objeto Counter es que inicializa automáticamente nuevas claves con un recuento de 0. Esto significa que no tienes que comprobar si una clave existe antes de incrementar su recuento, lo que simplifica el código para acumular recuentos.

Los Counter también vienen con métodos especiales. Por ejemplo, el método most_common() es muy útil para el análisis de datos.

## Get the two stocks with the most shares
>>> most_common_stocks = totals.most_common(2)
>>> print(most_common_stocks)
[('MSFT', 250), ('IBM', 150)]

Además, los Counter se pueden combinar utilizando operaciones aritméticas.

## Create another counter
>>> more = Counter()
>>> more['IBM'] = 75
>>> more['AA'] = 200
>>> more['ACME'] = 30
>>> print(more)
Counter({'AA': 200, 'IBM': 75, 'ACME': 30})

## Add two counters together
>>> combined = totals + more
>>> print(combined)
Counter({'AA': 300, 'MSFT': 250, 'IBM': 225, 'CAT': 150, 'GE': 95, 'ACME': 30})

defaultdict

El defaultdict es similar a un diccionario regular, pero tiene una característica única. Proporciona un valor predeterminado para las claves que aún no existen. Esto puede simplificar tu código, ya que ya no necesitas comprobar si una clave existe antes de usarla.

>>> from collections import defaultdict

## Group portfolio entries by stock name
>>> byname = defaultdict(list)
>>> for s in portfolio:
...     byname[s['name']].append(s)
...
>>> print(byname['IBM'])
[{'name': 'IBM', 'shares': 50, 'price': 91.1}, {'name': 'IBM', 'shares': 100, 'price': 70.44}]
>>> print(byname['AA'])
[{'name': 'AA', 'shares': 100, 'price': 32.2}]

Cuando creas un defaultdict(list), automáticamente crea una nueva lista vacía para cada nueva clave. Entonces, puedes agregar directamente a un valor de una clave incluso si la clave no existía antes. Esto elimina la necesidad de comprobar si la clave existe y crear una lista vacía manualmente.

También puedes usar otras funciones de fábrica predeterminadas. Por ejemplo, puedes usar int, float o incluso tu propia función personalizada.

## Use defaultdict with int to count items
>>> word_counts = defaultdict(int)
>>> words = ['apple', 'orange', 'banana', 'apple', 'orange', 'apple']
>>> for word in words:
...     word_counts[word] += 1
...
>>> print(word_counts)
defaultdict(<class 'int'>, {'apple': 3, 'orange': 2, 'banana': 1})

Estos tipos de contenedores especializados del módulo collections pueden hacer que tu código sea más conciso y eficiente cuando trabajas con datos.

Desafío de Análisis de Datos con Datos de la Autoridad de Transporte de Chicago

Ahora que has practicado el trabajo con diferentes estructuras de datos de Python y el módulo collections, es hora de poner estas habilidades en práctica en una tarea real de análisis de datos. En este experimento, analizaremos los datos de pasajeros de autobús de la Autoridad de Transporte de Chicago (CTA, por sus siglas en inglés). Esta aplicación práctica te ayudará a entender cómo usar Python para extraer información significativa de conjuntos de datos del mundo real.

Comprendiendo los Datos

Primero, echemos un vistazo a los datos de transporte con los que trabajaremos. En tu terminal de Python, ejecutarás algún código para cargar los datos y entender su estructura básica.

>>> import readrides
>>> rows = readrides.read_rides_as_dicts('/home/labex/project/ctabus.csv')
>>> print(len(rows))
## This will show the number of records in the dataset

>>> ## Let's look at the first record to understand the structure
>>> import pprint
>>> pprint.pprint(rows[0])

La declaración import readrides importa un módulo personalizado que tiene una función para leer los datos del archivo CSV. La función readrides.read_rides_as_dicts lee los datos del archivo CSV especificado y convierte cada fila en un diccionario. len(rows) nos da el número total de registros en el conjunto de datos. Al imprimir el primer registro usando pprint.pprint(rows[0]), podemos ver claramente la estructura de cada registro.

Los datos contienen registros diarios de pasajeros para diferentes rutas de autobús. Cada registro incluye:

  • route: El número de la ruta de autobús
  • date: La fecha en formato "YYYY - MM - DD"
  • daytype: Ya sea "W" para día laboral, "A" para sábado o "U" para domingo/festivo
  • rides: El número de pasajeros ese día

Tareas de Análisis

Resolvamos cada una de las preguntas del desafío una por una:

Pregunta 1: ¿Cuántas rutas de autobús existen en Chicago?

Para responder a esta pregunta, necesitamos encontrar todos los números de ruta únicos en el conjunto de datos. Usaremos una comprensión de conjunto para esta tarea.

>>> ## Get all unique route numbers using a set comprehension
>>> unique_routes = {row['route'] for row in rows}
>>> print(len(unique_routes))

Una comprensión de conjunto es una forma concisa de crear un conjunto. En este caso, iteramos sobre cada fila en la lista rows y extraemos el valor de route. Dado que un conjunto solo almacena elementos únicos, terminamos con un conjunto de todos los números de ruta únicos. Imprimir la longitud de este conjunto nos da el número total de rutas de autobús únicas.

También podemos ver cuáles son algunas de estas rutas:

>>> ## Print a few of the route numbers
>>> print(list(unique_routes)[:10])

Aquí, convertimos el conjunto de rutas únicas en una lista y luego imprimimos los primeros 10 elementos de esa lista.

Pregunta 2: ¿Cuántas personas tomaron el autobús número 22 el 2 de febrero de 2011?

Para esta pregunta, necesitamos filtrar los datos para encontrar el registro específico que coincide con la ruta y la fecha dadas.

>>> ## Find rides on route 22 on February 2, 2011
>>> target_date = "2011-02-02"
>>> target_route = "22"
>>>
>>> for row in rows:
...     if row['route'] == target_route and row['date'] == target_date:
...         print(f"Rides on route {target_route} on {target_date}: {row['rides']}")
...         break

Primero definimos las variables target_date y target_route. Luego, iteramos sobre cada fila en la lista rows. Para cada fila, comprobamos si la route y la date coinciden con nuestros valores objetivo. Si se encuentra una coincidencia, imprimimos el número de pasajeros y salimos del bucle ya que hemos encontrado el registro que buscábamos.

Puedes modificar esto para comprobar cualquier ruta en cualquier fecha cambiando las variables target_date y target_route.

Pregunta 3: ¿Cuál es el número total de pasajeros en cada ruta de autobús?

Usemos un Counter para calcular el total de pasajeros por ruta. Un Counter es una subclase de diccionario del módulo collections que se utiliza para contar objetos hashables.

>>> from collections import Counter
>>>
>>> ## Initialize a counter
>>> total_rides_by_route = Counter()
>>>
>>> ## Sum up rides for each route
>>> for row in rows:
...     total_rides_by_route[row['route']] += row['rides']
...
>>> ## View the top 5 routes by total ridership
>>> for route, rides in total_rides_by_route.most_common(5):
...     print(f"Route {route}: {rides:,} total rides")

Primero importamos la clase Counter del módulo collections. Luego, inicializamos un contador vacío llamado total_rides_by_route. A medida que iteramos sobre cada fila en la lista rows, agregamos el número de pasajeros de cada ruta al contador. Finalmente, usamos el método most_common(5) para obtener las 5 rutas con el mayor número total de pasajeros y imprimimos los resultados.

Pregunta 4: ¿Qué cinco rutas de autobús tuvieron el mayor aumento de pasajeros en diez años, desde 2001 hasta 2011?

Esta es una tarea más compleja. Necesitamos comparar el número de pasajeros en 2001 con el de 2011 para cada ruta.

>>> ## Create dictionaries to store total annual rides by route
>>> rides_2001 = Counter()
>>> rides_2011 = Counter()
>>>
>>> ## Collect data for each year
>>> for row in rows:
...     if row['date'].startswith('2001-'):
...         rides_2001[row['route']] += row['rides']
...     elif row['date'].startswith('2011-'):
...         rides_2011[row['route']] += row['rides']
...
>>> ## Calculate increases
>>> increases = {}
>>> for route in unique_routes:
...     if route in rides_2001 and route in rides_2011:
...         increase = rides_2011[route] - rides_2001[route]
...         increases[route] = increase
...
>>> ## Find the top 5 routes with the biggest increases
>>> import heapq
>>> top_5_increases = heapq.nlargest(5, increases.items(), key=lambda x: x[1])
>>>
>>> ## Display the results
>>> print("Top 5 routes with the greatest ridership increase from 2001 to 2011:")
>>> for route, increase in top_5_increases:
...     print(f"Route {route}: increased by {increase:,} rides")
...     print(f"  2001 rides: {rides_2001[route]:,}")
...     print(f"  2011 rides: {rides_2011[route]:,}")
...     print()

Primero creamos dos objetos Counter, rides_2001 y rides_2011, para almacenar el total de pasajeros de cada ruta en 2001 y 2011 respectivamente. A medida que iteramos sobre cada fila en la lista rows, comprobamos si la fecha comienza con '2001 -' o '2011 -' y agregamos los pasajeros al contador correspondiente.

Luego, creamos un diccionario vacío increases para almacenar el aumento de pasajeros de cada ruta. Iteramos sobre las rutas únicas y calculamos el aumento restando los pasajeros de 2001 de los de 2011 para cada ruta.

Para encontrar las 5 rutas con los mayores aumentos, usamos la función heapq.nlargest. Esta función toma el número de elementos a devolver (5 en este caso), el iterable (increases.items()) y una función clave (lambda x: x[1]) que especifica cómo comparar los elementos.

Finalmente, imprimimos los resultados, mostrando el número de la ruta, el aumento de pasajeros y el número de pasajeros en 2001 y 2011.

Este análisis identifica qué rutas de autobús experimentaron el mayor crecimiento en el número de pasajeros durante la década, lo que podría indicar cambios en los patrones de población, mejoras en el servicio u otras tendencias interesantes.

Puedes extender estos análisis de muchas maneras. Por ejemplo, podrías querer:

  • Analizar los patrones de pasajeros por día de la semana
  • Encontrar rutas con una disminución en el número de pasajeros
  • Comparar las variaciones estacionales en el número de pasajeros

Las técnicas que has aprendido en este laboratorio proporcionan una base sólida para este tipo de exploración y análisis de datos.

✨ Revisar Solución y Practicar

Resumen

En este laboratorio, has aprendido varias técnicas importantes de manipulación de datos en Python. Estas incluyen leer y procesar datos CSV en diccionarios, utilizar comprensiones de listas, conjuntos y diccionarios para la transformación de datos y aprovechar tipos de contenedores especializados del módulo collections. También aplicaste estas habilidades para realizar un análisis de datos significativo.

Estas técnicas son fundamentales para el análisis de datos en Python y son valiosas en diversos escenarios del mundo real. La capacidad de procesar, transformar y extraer información de los datos es crucial para los programadores de Python. Sigue practicando con tus propios conjuntos de datos para mejorar tu experiencia en el análisis de datos en Python.