Análisis de Datos con Python
El análisis de datos implica extraer información significativa de conjuntos de datos aparentemetne caóticos y descubrir patrones subyacentes. Para este propósito, Python ofrece tres bibliotecas esenciales:
- NumPy: Para operaciones numéricas eficientes
- Pandas: Para manipulación y análisis de datos
- Matplotlib: Para visualización de datos
NumPy
NumPy (Numerical Python) es una extensión fundamental para Python que permite trabajar con matrices multidimensionales y ofrece funciones matemáticas avanzadas.
Creación de Arreglos
# Crear arreglo unidimensional
import numpy as np
arr1d = np.array([1, 2, 3])
# Crear arreglo bidimensional
arr2d = np.array([[1, 2, 3], ['a', 'b', 'c']])
# Crear secuencias
print(np.linspace(1, 100, num=10)) # 10 números entre 1 y 100
print(np.arange(0, 10, 2)) # Números de 0 a 10 de 2 en 2
Atributos de Arreglos
np.random.seed(10)
random_arr = np.random.randint(0, 100, size=(4, 5))
print("Dimensiones:", random_arr.ndim)
print("Forma:", random_arr.shape)
print("Tamaño total:", random_arr.size)
print("Tipo de datos:", random_arr.dtype)
Operaciones Básicas
# Indexación
arr = np.random.randint(1, 100, size=(3, 4))
print("Segunda fila:", arr[1])
arr[1] = [90, 94, 30, 9]
# Rebanado
print("Primeras dos filas:", arr[0:2])
print("Primeras dos columnas:", arr[:, 0:2])
print("Primeras dos filas y columnas:", arr[0:2, 0:2])
# Reversión
print("Filas invertidas:", arr[::-1])
print("Columnas invertidas:", arr[:, ::-1])
Transformaciones
# Cambiar forma
print(arr.reshape((1, 12)))
print(arr.reshape((12, 1)))
# Concatenación
arr1 = np.array([[10, 16, 65, 29], [90, 94, 30, 9], [74, 1, 41, 37]])
arr2 = np.array([[20, 30, 40, 50], [60, 70, 80, 90], [10, 20, 30, 40]])
print(np.concatenate((arr1, arr2), axis=1))
Operaciones Agregadas
print("Suma total:", arr.sum())
print("Suma por columnas:", arr.sum(axis=0))
print("Suma por filas:", arr.sum(axis=1))
print("Máximo:", arr.max())
print("Máximo por columnas:", arr.max(axis=0))
print("Máximo por filas:", arr.max(axis=1))
print("Promedio:", arr.mean())
print("Promedio por columnas:", arr.mean(axis=0))
print("Promedio por filas:", arr.mean(axis=1))
Ordenamiento
# Ordenar sin modificar el original
sorted_arr = np.sort(arr, axis=0)
print("Ordenado por columnas:", sorted_arr)
# Ordenar modificando el original
arr.sort(axis=1)
print("Ordenado por filas:", arr)
Pandas
Pandas proporciona estructuras de datos y operaciones para manipular datos tabulares de manera eficiente.
Series
import pandas as pd
# Crear Series
s1 = pd.Series([1, 2, 3])
s2 = pd.Series([1, 2, 3], index=['x', 'y', 'z'])
s3 = pd.Series({'x': 1, 'y': 2, 'z': 3})
s4 = pd.Series({'x': 1, 'y': 2, 'z': 3}, index=['x', 'z'], name='Datos')
Indexación y Filtrado
s = pd.Series([1, 2, 3], index=['a', 'b', 'c'])
# Acceso por índice
print(s['a'])
print(s.loc['a'])
print(s.iloc[0])
# Filtrado
print(s[s > 1])
Valores Únicos
s = pd.Series([1, 2, 3, 3, 2, 4])
print("Valores únicos:", s.unique())
Operaciones con Series
s1 = pd.Series([1, 2, 3], index=['a', 'b', 'c'])
s2 = pd.Series([1, 2, 3], index=['a', 'd', 'c'])
s = s1 + s2
print("Operación con alineación automática:", s)
print("Valores nulos:", s.isnull())
print("Valores no nulos:", s.notnull())
print("Filtrar no nulos:", s[s.notnull()])
DataFrame
# Crear DataFrame
df = pd.DataFrame({
'col1': ['a', 'y', 'z'],
'col2': [1, 2, 3]
}, columns=['col1', 'col2'])
# Crear desde ndarray
df = pd.DataFrame(
data=np.random.randint(0, 100, size=(3, 4)),
index=['a', 'b', 'c'],
columns=['A', 'B', 'C', 'D']
)
# Crear desde diccionario
data = {'k': ['a', 'b', 'c'], 'v': [1, 2, 3]}
df = pd.DataFrame(data)
Indexación y Filtrado en DataFrame
df = pd.DataFrame({
'col1': ['a', 'y', 'z'],
'col2': [1, 2, 3]
}, columns=['col1', 'col2'])
# Acceso a columnas
print(df['col1'])
print(df[['col1', 'col2']])
# Acceso a filas
print(df.loc['a'])
print(df.iloc[0])
# Acceso a elementos
print(df['col1']['a'])
Operacinoes con DataFrame
df1 = pd.DataFrame(np.random.randint(0, 100, size=(3, 4)))
df2 = pd.DataFrame(np.random.randint(0, 100, size=(3, 3)))
# Concatenación
print(pd.concat((df1, df2)))
# Fusión
df1 = pd.DataFrame({'employee': ['Bob', 'Jake', 'Lisa'],
'group': ['Accounting', 'Engineering', 'Engineering']})
df2 = pd.DataFrame({'employee': ['Lisa', 'Bob', 'Jake'],
'hire_date': [2004, 2008, 2012]})
print(pd.merge(df1, df2))
Ejemplo de Análisis de Datos Financieros
import pandas as pd
import tushare as ts
# Configurar token y obtener datos
ts.set_token('your_token_here')
pro = ts.pro_api()
df = ts.get_k_data('600519', start='1900-01-01')
df.to_csv('./maotai.csv')
# Leer datos y limpiar
df = pd.read_csv('./maotai.csv', index_col='date', parse_dates=['date'])
df.drop(labels='Unnamed: 0', axis=1, inplace=True)
# Encontrar días con subida > 3%
up_days = df.loc[(df['close'] - df['open']) / df['open'] > 0.03].index
# Encontrar días con caída > 2% respecto al cierre anterior
down_days = df.loc[(df['open'] - df['close'].shift(1))/df['close'].shift(1) < -0.02].index
Procesamiento de Datos
Manejo de Valores Nulos
df = pd.DataFrame(data=np.random.randint(0, 100, size=(3, 4)))
df.iloc[0, 0] = None
df.iloc[1, 1] = np.nan
df.iloc[2, 2] = None
# Eliminar filas con valores nulos
df_clean = df.dropna(axis=0, how='any')
# Rellenar valores nulos
df_filled = df.fillna(12345)
Detección y Eliminación de Duplicados
df = pd.DataFrame(np.random.randint(0, 100, size=(8, 5)))
print("Duplicados:", df.duplicated())
df_unique = df.drop_duplicates()
Tratamiento de Valores Atípicos
df = pd.DataFrame(np.random.random(size=(100, 3)), columns=['A', 'B', 'C'])
std_twice = df['C'].std() * 2
outliers = df.loc[df['C'] > std_twice].index
df_clean = df.drop(labels=outliers)
Transformaciones de Datos
df = pd.DataFrame(data=np.random.randint(1, 100, size=(8, 5)))
# Reemplazar valores
df_replaced = df.replace(to_replace=10, value='ten')
# Mapeo de valores
name_map = {'Ana': 'A', 'Bob': 'B', 'Carlos': 'C'}
df['nick'] = df['name'].map(name_map)
Muestreo de Datos
df = pd.DataFrame(np.random.rand(5, 3), columns=list('ABC'))
print("Muestreo:", df.take([1, 0, 2]))
Agrupación y Agregación
df = pd.DataFrame({
'item': ['Apple', 'Banana', 'Orange', 'Banana', 'Orange', 'Apple'],
'price': [4, 3, 3, 2.5, 4, 2],
'color': ['red', 'yellow', 'yellow', 'green', 'green', 'green'],
'weight': [12, 20, 50, 30, 20, 44]
})
# Agrupar por item y calcular promedio
grouped = df.groupby('item').mean()
print("Promedio por item:", grouped)
Operaciones Avanzadas
def custom_mean(s):
return sum(s) / len(s)
# Aplicar función personalizada
result = df.groupby('item')['price'].apply(custom_mean)
print("Promedio personalizado:", result)
# Transformar datos
transformed = df.groupby('item')['price'].transform(custom_mean)
print("Datos transformados:", transformed)
Análisis con Algoritmos
Regresión Lineal
from sklearn.linear_model import LinearRegression
# Preparar datos
X = np.array(city_dist).reshape(-1, 1)
y = np.array(max_temp)
# Crear y entrenar modelo
model = LinearRegression()
model.fit(X, y)
# Evaluar modelo
print("Coeficiente:", model.coef_)
print("Intercepto:", model.intercept_)
print("R²:", model.score(X, y))
KNN (k-vecinos más cercanos)
from sklearn.neighbors import KNeighborsClassifier
# Preparar datos
X_train = feature[:4950]
y_train = target[:4950]
X_test = feature[4950:]
y_test = target[4950:]
# Crear y entrenar modelo
knn = KNeighborsClassifier(n_neighbors=9)
knn.fit(X_train, y_train)
# Evaluar modelo
print("Precisión:", knn.score(X_test, y_test))