Python se ha convertido en el lenguaje de programación dominante en la ciencia de datos, y no es por casualidad. Su combinación única de simplicidad, legibilidad y potencia lo ha transformado en la herramienta preferida por analistas, científicos de datos e investigadores en todo el mundo.
En este curso, construiremos desde los fundamentos del lenguaje hasta las técnicas avanzadas de manipulación y análisis de datos. Aprenderás a transformar datos crudos en conocimientos accionables, descubrir patrones ocultos y comunicar tus hallazgos de manera efectiva a través de visualizaciones impactantes.
La habilidad de programar en Python para ciencia de datos te permitirá abordar problemas complejos, tomar decisiones basadas en evidencia y generar valor en prácticamente cualquier industria o campo de investigación. ¡Comencemos este fascinante viaje al mundo del análisis de datos con Python!
Contrario a lo que muchos piensan, el nombre del lenguaje Python no hace referencia a la serpiente, sino a una peculiar fuente de inspiración: el grupo cómico británico "Monty Python". Guido van Rossum, el creador del lenguaje, era fan del programa de televisión "Monty Python's Flying Circus" y decidió nombrar su creación en honor a este show.
Python nació a finales de los años 80 como un proyecto personal de Van Rossum mientras trabajaba en el Centro para las Matemáticas y la Informática (CWI) en los Países Bajos. Su objetivo era crear un lenguaje que fuera accesible para principiantes pero lo suficientemente potente para los expertos. La primera versión pública (Python 0.9.0) se lanzó en febrero de 1991.
A lo largo de su evolución, Python ha mantenido sus principios fundamentales de diseño, resumidos en "El Zen de Python" (accesible escribiendo import this en cualquier intérprete de Python). Este conjunto de 19 aforismos incluye ideas como "Lo simple es mejor que lo complejo" y "La legibilidad cuenta", filosofías que han contribuido enormemente a la popularidad del lenguaje en el campo de la ciencia de datos.
Antes de comenzar a programar, necesitas tener Python instalado y un ambiente de desarrollo en tu computadora. Puedes seguir nuestra guía de instalación de Python para descargar e instalar las versiones adecuadas para tu sistema operativo.
Ahora que conoces un poco sobre Python, comencemos a experimentar. Una de las formas más sencillas de trabajar con Python es utilizando un intérprete o "shell", un entorno donde puedes escribir código Python y ver inmediatamente los resultados.
Empecemos con algo simple y usemos Python como una calculadora:
# Una simple operación aritmética
4 + 5
El intérprete de Python interpreta lo que escribiste y muestra el resultado de tu cálculo, 9. El shell que usamos habitualmente para trabajar es IPython (Python Interactivo), una versión mejorada del intérprete estándar de Python que incluye muchas funcionalidades útiles para la ciencia de datos.
Además de trabajar interactivamente con Python, también puedes ejecutar scripts de Python. Estos son simplemente archivos de texto con la extensión .py que contienen una lista de comandos Python que se ejecutan secuencialmente, casi como si estuvieras escribiendo los comandos en el shell tú mismo, línea por línea.
Veamos un ejemplo simple de script:
# Este es un script de Python simple
# Realizamos algunos cálculos básicos
resultado = 4 + 5
print("El resultado es:", resultado)
Observa que en los scripts, necesitas usar explícitamente la función print() si quieres generar alguna salida. Colocar tu código en scripts de Python en lugar de escribir cada paso interactivamente te ayudará a mantener la estructura y evitará tener que reescribir todo una y otra vez si quieres hacer un cambio; simplemente haces el cambio en el script y ejecutas todo de nuevo.
print() en tus scripts, no verás ningún resultado en la salida, aunque el código se ejecute correctamente.
Ahora que tienes una idea de las diferentes formas de trabajar con Python, estás listo para comenzar. Te recomendamos usar el intérprete para experimentar y probar ideas rápidas, mientras que los scripts son ideales para soluciones más permanentes y complejas.
A lo largo de este curso, iremos construyendo tus habilidades de programación para ciencia de datos paso a paso. No te preocupes si no tienes experiencia previa en programación; Python es conocido por ser amigable para principiantes y el enfoque práctico de este curso te ayudará a adquirir confianza rápidamente.
¡Comencemos este fascinante viaje juntos y no olvides divertirte mientras aprendes!
Python maneja diversos tipos de datos que son fundamentales para almacenar y manipular información. Cada tipo de dato tiene sus propias características y operaciones asociadas.
Python tiene varios tipos numéricos que utilizaremos constantemente en análisis de datos:
# Números enteros (int)
5
-10
42
# Operaciones con enteros
print(10 + 5) # Suma
print(20 - 7) # Resta
print(6 * 8) # Multiplicación
print(100 // 6) # División entera
print(17 % 5) # Módulo (resto de la división)
print(2 ** 8) # Potenciación (2 elevado a 8)
Las operaciones con números enteros son precisas y eficientes. Observa que la división normal (/) siempre devuelve un número de punto flotante, mientras que la división entera (//) devuelve un entero truncando la parte decimal.
# Números de punto flotante (float)
3.14
-0.001
2.5e6 # Notación científica: 2.5 × 10^6
# Operaciones con flotantes
print(3.5 + 2.1) # Suma
print(9.8 - 4.2) # Resta
print(2.5 * 3.0) # Multiplicación
print(7.0 / 2.0) # División
print(2.5 ** 2.0) # Potenciación con flotantes
Los valores booleanos representan la verdad lógica: True (verdadero) o False (falso). Son fundamentales para crear condiciones y expresiones lógicas:
# Valores booleanos
True
False
# Operaciones lógicas
print(True and False) # AND lógico
print(True or False) # OR lógico
print(not True) # NOT lógico
# Operaciones de comparación que devuelven booleanos
print(5 > 3) # Mayor que
print(10 <= 10) # Menor o igual que
print(7 == 7) # Igualdad
print(5 != 10) # Desigualdad
if y los bucles while, que veremos más adelante.
Las cadenas de texto, o strings, son secuencias de caracteres encerrados entre comillas:
# Strings
print("Hola, mundo")
print('Python para Ciencia de Datos')
Podemos utilizar la función type() para determinar el tipo de dato de cualquier valor en Python:
# Verificando diferentes tipos
print(type(42))
print(type(3.14))
print(type(True))
print(type("Hola"))
Una de las características fundamentales de Python es su manejo de variables. En Python, no necesitas declarar el tipo de variable antes de usarla, lo que hace que el código sea más limpio y fácil de escribir.
# Asignación de variables
nombre = "Carlos"
edad = 28
peso = 70.5
# Asignación múltiple
x, y, z = 10, "Hola", True
print(nombre, edad, peso)
print(x, y, z)
Como puedes ver, Python infiere el tipo de la variable según el valor que le asignas. Esto se conoce como "tipado dinámico".
Para nombrar variables en Python, es importante seguir estas convenciones:
# Ejemplos de nombres de variables válidos
mi_variable = 10
contador1 = 0
_variable_privada = "secreto"
# Ejemplos de nombres de variables inválidos
# 1variable = 20 # No puede comenzar con número
# mi-variable = 30 # No puede contener guiones
# mi variable = 40 # No puede contener espacios
En Python, es importante entender que los operadores pueden comportarse de manera diferente dependiendo del tipo de datos con el que trabajas. Observa estos ejemplos:
# Suma de enteros
5 + 7
# Concatenación de cadenas
"Hola" + " Python"
Para los enteros, el operador + realiza una suma aritmética, mientras que para las cadenas (strings), el mismo operador concatena o une los textos. Este es un principio general en Python: el comportamiento del código depende de los tipos de datos con los que estás trabajando.
Podemos almacenar estos valores en variables para reutilizarlos:
# Creando variables con diferentes tipos
numero_a = 5
numero_b = 7
resultado_numeros = numero_a + numero_b
texto_a = "Hola"
texto_b = " Python"
resultado_textos = texto_a + texto_b
# Mostrando los resultados
print(resultado_numeros)
print(resultado_textos)
# Comprobando el tipo de las variables resultado
type(resultado_numeros)
type(resultado_textos)
Existen varias formas de formatear strings en Python:
# Usando f-strings (Python 3.6+)
nombre = "Juan"
edad = 25
print(f"Hola, me llamo {nombre} y tengo {edad} años.")
# Usando método format()
print("Hola, me llamo {} y tengo {} años.".format(nombre, edad))
# Usando % (estilo antiguo)
print("Hola, me llamo %s y tengo %d años." % (nombre, edad))
Puedes obtener entrada del usuario con la función input():
# Solicitar datos al usuario
nombre = input("Introduce tu nombre: ")
edad = int(input("Introduce tu edad: ")) # Convertir a entero
print(f"Hola {nombre}, tienes {edad} años.")
input() siempre devuelve un string, por eso necesitamos usar funciones como int() o float() para convertir la entrada a números cuando sea necesario.
Python ofrece varias estructuras de datos incorporadas que son fundamentales para el análisis de datos. Estas estructuras permiten almacenar, organizar y manipular colecciones de datos de manera eficiente.
Las listas son una de las estructuras de datos más versátiles en Python. Una lista es una colección ordenada y mutable de elementos que pueden ser de diferentes tipos.
# Crear una lista
numeros = [1, 2, 3, 4, 5]
mixta = [10, "hola", True, 3.14]
# Verificar el tipo
type(numeros)
Los elementos de una lista están indexados, comenzando desde 0 para el primer elemento. También se pueden usar índices negativos para acceder a elementos desde el final.
# Lista de ejemplo
frutas = ["manzana", "banana", "cereza", "durazno", "fresa"]
# Acceder a elementos por índice
print(frutas[0]) # Primer elemento
print(frutas[2]) # Tercer elemento
print(frutas[-1]) # Último elemento
print(frutas[-2]) # Penúltimo elemento
La indexación también funciona con strings, ya que son secuencias de caracteres:
# Indexación en strings
nombre = "Python"
print(nombre[0]) # Primera letra
print(nombre[-1]) # Última letra
IndexError. Siempre verifica que el índice sea válido antes de acceder a él.
El slicing permite seleccionar un subconjunto de elementos de una lista o string utilizando la sintaxis [inicio:fin:paso], donde inicio es el índice donde comienza la selección (incluido), fin es el índice donde termina (excluido) y paso define el intervalo entre elementos:
# Slicing de listas
numeros = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# Sintaxis: lista[inicio:fin:paso]
print(numeros[2:5]) # Elementos del índice 2 al 4
print(numeros[:4]) # Elementos desde el inicio hasta el índice 3
print(numeros[6:]) # Elementos desde el índice 6 hasta el final
print(numeros[1:8:2]) # Elementos del 1 al 7 con paso 2
print(numeros[::-1]) # Lista invertida
El slicing funciona de la misma manera con strings. Observa los índices positivos y negativos para la palabra "Python":
+---+---+---+---+---+---+ | P | y | t | h | o | n | +---+---+---+---+---+---+ 0 1 2 3 4 5 -6 -5 -4 -3 -2 -1
# Slicing con strings
texto = "Python"
# Diferentes formas de hacer slicing
print(texto[0:2]) # Primeros dos caracteres
print(texto[2:]) # Desde el tercer carácter hasta el final
print(texto[:4]) # Desde el inicio hasta el cuarto carácter (excluido)
print(texto[-2:]) # Últimos dos caracteres
print(texto[::2]) # Caracteres con paso 2 (posiciones pares)
print(texto[::-1]) # String invertido
Puedes tener listas dentro de listas (estructuras anidadas) y acceder a sus elementos utilizando múltiples índices:
# Lista anidada con múltiples niveles
arreglo = [1, 2, 3, [4, 5, ["colombia"]]] # Lista con otra lista al interior
# Acceder a elementos anidados
print(arreglo[0]) # Primer elemento
print(arreglo[3]) # Cuarto elemento (que es una lista)
print(arreglo[3][0]) # Primer elemento de la lista anidada
print(arreglo[3][2]) # Tercer elemento de la lista anidada (otra lista)
print(arreglo[3][2][0]) # Elemento dentro de la lista doblemente anidada
Las listas son mutables, lo que significa que puedes modificarlas después de crearlas:
# Métodos para agregar elementos
frutas = ["manzana", "banana", "cereza"]
# Agregar un elemento al final
frutas.append("durazno")
print(frutas)
# Insertar un elemento en una posición específica
frutas.insert(1, "arándano")
print(frutas)
# Extender una lista con otra lista
frutas.extend(["fresa", "uva"])
print(frutas)
Puedes cambiar el valor de un elemento existente asignándole un nuevo valor:
# Modificar elementos por índice
colores = ["rojo", "verde", "azul"]
print(colores)
# Cambiar el segundo elemento
colores[1] = "amarillo"
print(colores)
# También puedes modificar múltiples elementos con slicing
numeros = [1, 2, 3, 4, 5]
numeros[1:4] = [20, 30, 40]
print(numeros)
Existen varios métodos para eliminar elementos de una lista:
# Diferentes formas de eliminar elementos
frutas = ["manzana", "banana", "cereza", "durazno", "fresa"]
print(frutas)
# Eliminar un elemento por su valor
frutas.remove("cereza")
print(frutas)
# Eliminar un elemento por su índice y obtenerlo
fruta_eliminada = frutas.pop(1)
print(f"Se eliminó: {fruta_eliminada}")
print(frutas)
# Eliminar el último elemento
ultima = frutas.pop()
print(f"Último elemento: {ultima}")
print(frutas)
# Eliminar un elemento por índice sin devolverlo
del frutas[0]
print(frutas)
remove() elimina solo la primera ocurrencia del valor. Si necesitas eliminar todas las ocurrencias, deberás usar un bucle o comprensión de listas.
Puedes combinar listas utilizando el operador + o el método extend():
# Concatenar listas
lista1 = [1, 2, 3]
lista2 = [4, 5, 6]
# Usando el operador +
lista_combinada = lista1 + lista2
print(lista_combinada)
# Usando extend (modifica la lista original)
numeros_originales = [10, 20, 30]
numeros_adicionales = [40, 50]
numeros_originales.extend(numeros_adicionales)
print(numeros_originales)
+ y extend() es que el operador + crea una nueva lista, mientras que extend() modifica la lista original.
Los diccionarios son colecciones no ordenadas de pares clave-valor. Son ideales para almacenar y recuperar datos mediante una clave única.
# Crear un diccionario
persona = {
"nombre": "Ana",
"edad": 28,
"profesion": "Data Scientist",
"lenguajes": ["Python", "R", "SQL"]
}
# Acceder a valores por clave
print(persona["nombre"])
print(persona["lenguajes"])
# Método get (seguro, devuelve None o un valor predeterminado si la clave no existe)
print(persona.get("salario")) # La clave no existe
print(persona.get("salario", "No especificado")) # Valor predeterminado
Los diccionarios son mutables, por lo que puedes añadir, modificar o eliminar elementos:
# Modificar un diccionario
persona = {"nombre": "Ana", "edad": 28}
# Agregar nuevos pares clave-valor
persona["ciudad"] = "Barcelona"
persona["email"] = "ana@ejemplo.com"
print(persona)
# Modificar un valor existente
persona["edad"] = 29
print(persona)
# Eliminar un par clave-valor
del persona["email"]
print(persona)
# Obtener todas las claves y valores
print(persona.keys())
print(persona.values())
print(persona.items()) # Pares clave-valor como tuplas
Las tuplas son secuencias inmutables, lo que significa que no pueden modificarse después de crearse. Son similares a las listas, pero se definen con paréntesis en lugar de corchetes.
# Crear tuplas
coordenadas = (10.5, 20.8)
persona = ("Ana", 28, "Ingeniera")
# Tupla con un solo elemento (necesita una coma)
singleton = (42,)
# Verificar el tipo
print(type(coordenadas))
Aunque las tuplas son inmutables, puedes acceder a sus elementos igual que en las listas:
# Acceder a elementos de una tupla
persona = ("Ana", 28, "Ingeniera")
print(persona[0]) # Primer elemento
print(persona[-1]) # Último elemento
# Desempaquetar una tupla (muy útil)
nombre, edad, profesion = persona
print(f"{nombre} tiene {edad} años y es {profesion}")
# Slicing también funciona con tuplas
coordenadas = (1, 2, 3, 4, 5)
print(coordenadas[1:4])
TypeError.
Python permite convertir entre diferentes tipos de datos utilizando funciones de conversión:
# Conversión entre tipos numéricos
entero = 42
flotante = float(entero) # int a float
print(flotante)
decimal = 3.14
entero_redondeado = int(decimal) # float a int (trunca, no redondea)
print(entero_redondeado)
# Conversión entre secuencias
lista = [1, 2, 3]
tupla = tuple(lista) # lista a tupla
print(tupla)
tupla = (4, 5, 6)
lista = list(tupla) # tupla a lista
print(lista)
# Strings a números y viceversa
numero_str = "123"
numero_int = int(numero_str) # string a int
print(numero_int + 7)
numero = 456
numero_str = str(numero) # número a string
print(numero_str + " es un número")
# Conversión entre diccionarios y listas
lista_pares = [("nombre", "Juan"), ("edad", 30)]
diccionario = dict(lista_pares) # lista de tuplas a diccionario
print(diccionario)
diccionario = {"a": 1, "b": 2}
lista_items = list(diccionario.items()) # items del diccionario a lista
print(lista_items)
Las sentencias de control permiten modificar el flujo de ejecución de un programa, haciendo que ciertos bloques de código se ejecuten o se omitan según determinadas condiciones, o que se repitan varias veces. A diferencia de otros lenguajes que utilizan llaves {} o palabras clave como begin-end, Python utiliza la indentación (espacios al inicio de cada línea) para definir bloques de código.
Las estructuras condicionales permiten ejecutar diferentes bloques de código dependiendo de si ciertas condiciones son verdaderas o falsas. En Python, utilizamos if, elif (else if) y else para construir estas estructuras.
# Estructura básica de condicionales
edad = 18
if edad < 18:
print("Eres menor de edad")
elif edad == 18:
print("Acabas de cumplir la mayoría de edad")
else:
print("Eres mayor de edad")
# Condicionales anidados
puntuacion = 85
if puntuacion >= 60:
print("Aprobado")
if puntuacion >= 90:
print("Sobresaliente")
elif puntuacion >= 80:
print("Notable")
else:
print("Bien")
else:
print("Reprobado")
and, or y not para combinar múltiples condiciones en una sola expresión condicional.
# Uso de operadores lógicos en condicionales
edad = 25
tiene_licencia = True
if edad >= 18 and tiene_licencia:
print("Puede conducir")
else:
print("No puede conducir")
# Expresiones condicionales compactas (operador ternario)
mensaje = "Puede votar" if edad >= 18 else "No puede votar"
print(mensaje)
Los ciclos for en Python son extremadamente versátiles y se utilizan para iterar sobre secuencias (como listas, tuplas, diccionarios, conjuntos o strings) o cualquier objeto iterable. A diferencia de otros lenguajes, el ciclo for de Python se asemeja más al "foreach" de otros lenguajes.
# Iteración básica con for
for i in range(5):
print(i, end=" ")
print("\n") # Nueva línea
# Iteración sobre una lista
frutas = ["manzana", "banana", "cereza"]
for fruta in frutas:
print(f"Me gusta la {fruta}")
# Iteración con índices usando enumerate
for indice, fruta in enumerate(frutas):
print(f"Índice {indice}: {fruta}")
También puedes iterar sobre diccionarios de varias maneras:
# Iteración sobre diccionarios
persona = {"nombre": "Ana", "edad": 28, "ciudad": "Madrid"}
# Iterar sobre las claves
for clave in persona:
print(clave)
# Iterar sobre los valores
for valor in persona.values():
print(valor)
# Iterar sobre pares clave-valor
for clave, valor in persona.items():
print(f"{clave}: {valor}")
Los ciclos while ejecutan un bloque de código mientras una condición específica sea verdadera. Son útiles cuando no sabes de antemano cuántas iteraciones necesitarás.
# Ciclo while básico
contador = 0
while contador < 5:
print(contador, end=" ")
contador += 1
print("\n") # Nueva línea
# Uso de while para validar entrada
"""
# Este código solicitaría entrada al usuario en un entorno interactivo
numero = -1
while numero < 0:
try:
numero = int(input("Ingrese un número positivo: "))
if numero < 0:
print("El número debe ser positivo.")
except ValueError:
print("Por favor, ingrese un número válido.")
"""
# Ejemplo alternativo sin input
numero = -1
intentos = 0
valores = ["-5", "texto", "10"] # Simulación de entradas
while numero < 0 and intentos < len(valores):
try:
numero = int(valores[intentos])
if numero < 0:
print(f"El número {numero} debe ser positivo.")
except ValueError:
print(f"'{valores[intentos]}' no es un número válido.")
intentos += 1
if numero >= 0:
print(f"Número válido: {numero}")
else:
print("No se pudo obtener un número válido")
while, ya que pueden generar bucles infinitos si la condición nunca se vuelve falsa. Asegúrate de que algo dentro del bucle modifique eventualmente la condición.
Python proporciona dos instrucciones especiales para controlar el flujo dentro de los ciclos: break y continue. Estas te permiten alterar el comportamiento normal de un ciclo según ciertas condiciones.
La instrucción break termina el ciclo actual por completo y transfiere la ejecución a la siguiente instrucción después del ciclo.
# Uso de break en un ciclo for
print("Ejemplo de break con for:")
for i in range(10):
if i == 5:
print("¡Encontramos el 5! Saliendo del ciclo.")
break
print(i, end=" ")
print("\n") # Nueva línea
# Uso de break en un ciclo while
print("Ejemplo de break con while:")
contador = 0
while True: # Ciclo infinito potencial
print(contador, end=" ")
contador += 1
if contador >= 5:
print("\nLlegamos a 5. Saliendo del ciclo infinito.")
break
La instrucción continue salta el resto del código en la iteración actual y avanza a la siguiente iteración del ciclo.
# Uso de continue en un ciclo for
print("Ejemplo de continue con for:")
for i in range(10):
if i % 2 == 0: # Si i es par
continue
print(i, end=" ")
print("\n") # Nueva línea
# Uso de continue en un ciclo while
print("Ejemplo de continue con while:")
contador = 0
while contador < 10:
contador += 1
if contador % 2 == 0: # Si contador es par
continue
print(contador, end=" ")
break es útil cuando encuentras lo que estabas buscando y no necesitas seguir iterando, mientras que continue es útil cuando quieres omitir ciertos elementos en tu procesamiento.
Las comprensiones de listas (list comprehensions) son una característica poderosa y concisa de Python que te permite crear nuevas listas aplicando una expresión a cada elemento de una secuencia existente, opcionalmente filtrando elementos con una condición.
# Forma básica de list comprehension
numeros = [1, 2, 3, 4, 5]
# Crear una lista con el cuadrado de cada número
cuadrados = [x**2 for x in numeros]
print(cuadrados)
# List comprehension con condición (filtro)
pares = [x for x in numeros if x % 2 == 0]
print(pares)
# Equivalente usando un ciclo for tradicional
cuadrados_tradicional = []
for x in numeros:
cuadrados_tradicional.append(x**2)
print(cuadrados_tradicional)
# List comprehension con múltiples condiciones
numeros = list(range(1, 11))
filtrados = [x for x in numeros if x % 2 == 0 if x % 3 != 0]
print(filtrados) # Números pares que no son divisibles por 3
# List comprehension con expresión if-else
clasificados = ["par" if x % 2 == 0 else "impar" for x in numeros]
print(clasificados)
También puedes utilizar list comprehensions para aplanar estructuras de datos anidadas, convirtiendo una lista de listas en una sola lista:
# Aplanar listas anidadas con list comprehension
canastas = [
["manzana", "pera", "uva"], # Frutas
["zanahoria", "apio", "lechuga"], # Vegetales
["naranja", "mandarina", "limón"] # Cítricos
]
# Convertir múltiples canastas en una sola lista de alimentos
todos_alimentos = [alimento for canasta in canastas for alimento in canasta]
print(todos_alimentos)
# Equivalente usando bucles for tradicionales
lista_tradicional = []
for canasta in canastas:
for alimento in canasta:
lista_tradicional.append(alimento)
print(lista_tradicional)
for es importante: el bucle externo va primero, seguido por el bucle interno. Esto puede parecer contraintuitivo al principio, pero reflexiona sobre cómo escribirías los bucles for anidados normales.
Las funciones son bloques de código reutilizables diseñados para realizar una tarea específica. Son fundamentales en programación por varias razones:
En ciencia de datos, las funciones son especialmente importantes para crear procesos analíticos reproducibles y para manipular conjuntos de datos de manera consistente.
Las funciones en Python se definen usando la palabra clave def, seguida del nombre de la función y paréntesis que pueden contener parámetros. El bloque de código de la función se indenta después de dos puntos.
# Función básica sin parámetros
def saludar():
print("¡Hola, bienvenido a Python!")
# Llamada a la función
saludar()
Las funciones pueden recibir parámetros (datos de entrada) y devolver valores utilizando la palabra clave return:
# Función con parámetros y valor de retorno
def cuadrado(numero):
return numero ** 2
# Llamada a la función con un argumento
resultado = cuadrado(5)
print(f"El cuadrado de 5 es: {resultado}")
# Función para sumar todos los elementos de una lista
def suma_lista(numeros):
total = 0
for num in numeros:
total += num
return total
# Probar la función
mi_lista = [1, 2, 3, 4, 5]
print(f"La suma de {mi_lista} es: {suma_lista(mi_lista)}")
Puedes establecer valores predeterminados para los parámetros, lo que los hace opcionales:
# Función con parámetros predeterminados
def potencia(base, exponente=2):
return base ** exponente
# Llamadas a la función
print(potencia(3)) # Usa el exponente predeterminado (2)
print(potencia(3, 4)) # Especifica un exponente diferente
Python incluye numerosas funciones incorporadas (built-in) que están disponibles sin necesidad de importar módulos. Estas funciones proporcionan funcionalidades esenciales para el manejo de datos y operaciones comunes.
abs() |
dict() |
help() |
min() |
setattr() |
all() |
dir() |
hex() |
next() |
slice() |
any() |
divmod() |
id() |
object() |
sorted() |
ascii() |
enumerate() |
input() |
oct() |
staticmethod() |
bin() |
eval() |
int() |
open() |
str() |
bool() |
exec() |
isinstance() |
ord() |
sum() |
bytearray() |
filter() |
issubclass() |
pow() |
super() |
bytes() |
float() |
iter() |
print() |
tuple() |
callable() |
format() |
len() |
property() |
type() |
chr() |
frozenset() |
list() |
range() |
vars() |
classmethod() |
getattr() |
locals() |
repr() |
zip() |
compile() |
globals() |
map() |
reversed() |
import() |
complex() |
hasattr() |
max() |
round() |
La función len() devuelve el número de elementos en un objeto. Funciona con cadenas, listas, tuplas, diccionarios y otros objetos iterables.
# Ejemplos de uso de len()
print(len("Python")) # Longitud de una cadena
print(len([1, 2, 3, 4, 5])) # Número de elementos en una lista
print(len({"a": 1, "b": 2})) # Número de pares clave-valor en un diccionario
print(len(range(0, 10, 2))) # Número de elementos en un rango
La función help() proporciona documentación integrada sobre objetos, funciones, módulos y tipos de datos en Python. Es una herramienta invaluable para aprender sobre las funcionalidades disponibles.
# Ejemplo de uso de help()
# help(print) # Muestra ayuda sobre la función print
# Ejemplo de la salida de help para len
print("La función len() devuelve la longitud (número de elementos) de un objeto.")
print("Sintaxis: len(objeto)")
print("Parámetros: objeto - una secuencia (string, lista, tupla, etc.) o colección (diccionario, set, etc.)")
print("Retorna: un entero que representa el número de elementos")
help() sin argumentos para iniciar una sesión de ayuda interactiva, o proporcionar un objeto específico como argumento para ver su documentación.
La función range() genera una secuencia de números. Es especialmente útil en bucles for y para crear listas de números.
# Ejemplos de uso de range()
# range con un solo argumento (fin, exclusivo)
print(list(range(5))) # 0 a 4
# range con dos argumentos (inicio, fin)
print(list(range(2, 8))) # 2 a 7
# range con tres argumentos (inicio, fin, paso)
print(list(range(1, 10, 2))) # Números impares del 1 al 9
print(list(range(10, 0, -1))) # Cuenta regresiva de 10 a 1
range() en Python 3 devuelve un objeto iterable, no una lista. Para ver los valores, necesitas convertirlo a una lista usando list() o iterarlo en un bucle.
La función enumerate() añade un contador a un iterable y devuelve un objeto enumerate que genera pares (índice, valor). Es ideal cuando necesitas tanto el índice como el valor durante la iteración.
# Ejemplos de uso de enumerate()
frutas = ["manzana", "banana", "cereza"]
# Iteración básica con enumerate
for i, fruta in enumerate(frutas):
print(f"Índice {i}: {fruta}")
# Usando enumerate con un valor inicial para el contador
for i, fruta in enumerate(frutas, start=1):
print(f"Fruta #{i}: {fruta}")
# Convertir enumerate a una lista de tuplas
print(list(enumerate(frutas)))
Los métodos son funciones que pertenecen a objetos específicos. A diferencia de las funciones independientes, los métodos están asociados a un tipo de dato particular y se invocan usando la notación de punto: objeto.metodo().
Los strings en Python tienen numerosos métodos para manipular texto. Estos métodos se pueden categorizar en grupos según su funcionalidad.
# Métodos de formato para strings
texto = "python es genial"
# Cambios de capitalización
print(texto.upper()) # Convierte a mayúsculas
print(texto.lower()) # Convierte a minúsculas
print(texto.capitalize()) # Primera letra en mayúscula
print(texto.title()) # Primera letra de cada palabra en mayúscula
# Alineación y relleno
print(texto.center(30, '-')) # Centra el texto en un espacio de 30 caracteres
print(texto.ljust(25, '*')) # Alinea a la izquierda en un espacio de 25
print(texto.rjust(25, '*')) # Alinea a la derecha en un espacio de 25
# Métodos de búsqueda para strings
texto = "Python es un lenguaje de programación versatil y poderoso"
# Verificar contenido
print(texto.startswith("Python")) # ¿Comienza con 'Python'?
print(texto.endswith("poderoso")) # ¿Termina con 'poderoso'?
print("lenguaje" in texto) # ¿Contiene 'lenguaje'?
# Encontrar posiciones
print(texto.find("lenguaje")) # Posición de 'lenguaje'
print(texto.find("Java")) # -1 si no se encuentra
print(texto.count("o")) # Cuenta ocurrencias de 'o'
# Métodos de sustitución para strings
texto = "Python es genial, Python es poderoso"
# Reemplazar texto
print(texto.replace("Python", "JavaScript")) # Reemplaza todas las ocurrencias
print(texto.replace("Python", "Java", 1)) # Reemplaza solo la primera ocurrencia
# Eliminar espacios en blanco
texto_con_espacios = " Python "
print(texto_con_espacios.strip()) # Elimina espacios al inicio y final
print(texto_con_espacios.lstrip()) # Elimina espacios al inicio
print(texto_con_espacios.rstrip()) # Elimina espacios al final
# Métodos de unión y división para strings
palabras = ["Python", "es", "genial"]
# Unir strings
print(" ".join(palabras)) # Une con espacios
print("-".join(palabras)) # Une con guiones
# Dividir strings
texto = "Python,Java,C++,JavaScript"
print(texto.split(",")) # Divide por comas
print(texto.split(",", 2)) # Limita a 2 divisiones
# Partir líneas
texto_multilinea = """Línea 1
Línea 2
Línea 3"""
print(texto_multilinea.splitlines()) # Divide por saltos de línea
replace(), upper(), etc., no modifican el string original, sino que devuelven una nueva copia modificada.
Las listas en Python tienen métodos que permiten modificar su contenido, reorganizar elementos y obtener información sobre ellos.
Añade un elemento al final de la lista.
# Método append()
frutas = ["manzana", "banana"]
frutas.append("cereza")
print(frutas)
Elimina y devuelve el elemento en la posición especificada. Si no se proporciona un índice, elimina y devuelve el último elemento.
# Método pop()
numeros = [10, 20, 30, 40, 50]
# Eliminar y obtener el último elemento
ultimo = numeros.pop()
print(f"Elemento eliminado: {ultimo}")
print(f"Lista actualizada: {numeros}")
# Eliminar y obtener un elemento específico
segundo = numeros.pop(1)
print(f"Segundo elemento: {segundo}")
print(f"Lista actualizada: {numeros}")
Crea una copia superficial de la lista.
# Método copy()
original = [1, 2, 3]
# Crear una copia de la lista
copia = original.copy()
print(f"Original: {original}, Copia: {copia}")
# Modificar la copia no afecta al original
copia.append(4)
print(f"Original después de modificar la copia: {original}")
print(f"Copia modificada: {copia}")
copy() crea una copia superficial, lo que significa que los objetos anidados (como listas dentro de listas) siguen siendo referencias compartidas. Para una copia profunda, usa el módulo copy y su función deepcopy().
Ordena los elementos de la lista in-place (modifica la lista original).
# Método sort()
numeros = [3, 1, 4, 1, 5, 9, 2]
# Ordenar de menor a mayor
numeros.sort()
print(f"Ordenados ascendente: {numeros}")
# Ordenar de mayor a menor
numeros.sort(reverse=True)
print(f"Ordenados descendente: {numeros}")
# Ordenar cadenas (alfabéticamente)
nombres = ["Zoe", "Ana", "Carlos", "Berta"]
nombres.sort()
print(f"Nombres ordenados: {nombres}")
# Ordenar por longitud de cadena
nombres.sort(key=len)
print(f"Nombres ordenados por longitud: {nombres}")
# Métodos para identificar elementos
frutas = ["manzana", "banana", "cereza", "banana", "durazno"]
# Contar ocurrencias
print(f"Número de bananas: {frutas.count('banana')}")
# Encontrar la posición de un elemento
print(f"Posición de cereza: {frutas.index('cereza')}")
# Verificar si un elemento existe
print(f"¿Hay manzanas? {'manzana' in frutas}")
print(f"¿Hay uvas? {'uva' in frutas}")
# Encontrar la primera ocurrencia en un rango
print(f"Posición de banana desde el índice 2: {frutas.index('banana', 2)}")
Python tiene un rico ecosistema de paquetes y librerías que extienden sus capacidades. Para utilizar estas librerías, necesitas instalarlas en tu entorno. Hay diferentes formas de hacerlo, dependiendo de tu entorno de trabajo.
PIP (Package Installer for Python) es el gestor de paquetes estándar para Python. Permite instalar, actualizar y eliminar paquetes de PyPI (Python Package Index).
# Instalar un paquete
pip install numpy
# Instalar una versión específica
pip install pandas==1.3.0
# Actualizar un paquete
pip install --upgrade matplotlib
# Instalar múltiples paquetes
pip install numpy pandas matplotlib seaborn
# Ver los paquetes instalados
pip list
# Desinstalar un paquete
pip uninstall scipy
También puedes instalar paquetes directamente desde un notebook de Jupyter utilizando el comando mágico ! seguido del comando pip.
# Instalar un paquete desde Jupyter Notebook
!pip install numpy
# O usar el comando system
import sys
!{sys.executable} -m pip install pandas
# Verificar la instalación
import numpy as np
print(f"NumPy versión: {np.__version__}")
import pandas as pd
print(f"Pandas versión: {pd.__version__}")
A continuación, se presentan algunos ejemplos que combinan funciones, métodos y paquetes para realizar tareas comunes en ciencia de datos.
# Ejemplo 1: Análisis básico de una lista de números
numeros = [4, 2, 7, 1, 8, 3, 5, 6]
def analizar_lista(lista):
"""Realiza un análisis básico de una lista de números."""
resultados = {
"cantidad": len(lista),
"suma": sum(lista),
"promedio": sum(lista) / len(lista) if lista else 0,
"minimo": min(lista) if lista else None,
"maximo": max(lista) if lista else None,
"ordenados": sorted(lista)
}
return resultados
# Usar la función
analisis = analizar_lista(numeros)
for clave, valor in analisis.items():
print(f"{clave.capitalize()}: {valor}")
# Ejemplo 2: Procesamiento de texto
texto = "Python es un lenguaje de programación versátil, poderoso y fácil de aprender."
def analizar_texto(texto):
"""Realiza un análisis básico de un texto."""
palabras = texto.lower().replace(".", "").replace(",", "").split()
resultados = {
"num_caracteres": len(texto),
"num_palabras": len(palabras),
"palabras_unicas": len(set(palabras)),
"palabra_mas_larga": max(palabras, key=len)
}
return resultados
# Usar la función
analisis_texto = analizar_texto(texto)
for clave, valor in analisis_texto.items():
print(f"{clave.replace('_', ' ').capitalize()}: {valor}")
Notebooks interactivos en Google Colab donde podrás practicar los conceptos básicos de Python para ciencia de datos. Ideal para consolidar lo aprendido en este capítulo con ejercicios prácticos y ejemplos ejecutables
Si deseas ampliar tus conocimientos sobre Python, aquí tienes algunos recursos recomendados:
Para aprender más sobre Python y su aplicación en ciencia de datos, recomendamos consultar estos recursos oficiales: