<jupyter_start><jupyter_text>Explorando Datasets - London Bike SharingEste documento tiene como propósito llevar a cabo los pasos durante un análisis de datos rutinario en un dataset como el London Bike Sharing.Fuente: [Kaggle - Data Analysis](https://www.kaggle.com/hmavrodiev/london-bike-sharing-dataset) MetadataEl data set está compuesto por la siguientes columnas:- "timestamp" - Campo de registro de fecha- "cnt" - La cuenta de bicicletas compartidas- "t1" - Temperatura real en grados Celsius- "t2" - Temperatura percibida en Celsius- "hum" - Porcentaje de humedad relativa- "windspeed" - Velocidad del viento km/h- "weathercode" - Categoría del clima- "isholiday" - boolean  - 1 Festivo / 0 no Festivo- "isweekend" - boolean  - 1 Si es en semana- "season" - Categorías meteorologicas de cada temporada: 0-primavera ; 1-verano; 2-otoño; 3-invierno. "weather_code" Descripción de las categorías del clima:- 1 = Clear ; mostly clear but have some values with haze/fog/patches of fog/ fog in vicinity - 2 = scattered clouds / few clouds - 3 = Broken clouds - 4 = Cloudy - 7 = Rain/ light Rain shower/ Light rain - 10 = rain with thunderstorm - 26 = snowfall - 94 = Freezing Fog  Objetivo:1. Cargar mi dataset2. Identificar los tipos de variables3. Si encuentro columnas que son tipo objeto y deberían ser formato fecha uso las funciones de pandas para dicha labor.<jupyter_code>!pip install --upgrade pandas
import pandas as pd
import numpy as np
pd.__version__<jupyter_output><empty_output><jupyter_text>Cuando trabajo con repositorio Local de información, cargo mis datos así:<jupyter_code>df_lmerged = pd.read_csv('../../Data/london_merged.csv')
df_lmerged<jupyter_output><empty_output><jupyter_text>Explorar los tipos de dato.<jupyter_code>df_lmerged.dtypes<jupyter_output><empty_output><jupyter_text>Parseando Fechas.Tranforma el tipo de dato de la columna timestamp de objeto a fecha. ¿Por qué es importante parsear la columna de tipo objeto a tipo fecha?.<jupyter_code>df_lmerged['timestamp'] = pd.to_datetime(df_lmerged['timestamp'])
df_lmerged['timestamp']
df_lmerged.dtypes<jupyter_output><empty_output><jupyter_text>Cuando la columna ya tiene formato tipo `datetime` puedo usar método de `.hour` para crear una columna de horas, porque puedo acceder a esta así como minutos, segundos.<jupyter_code>df_lmerged['hour'] = df_lmerged['timestamp'].dt.hour
df_lmerged['hour']<jupyter_output><empty_output><jupyter_text>Creando Dataframe de trabajo.Aqui lo que hice fue que eliminé la columna de tiempo con el propósito de posteriomente realizar operaciones matemáticas sobre un dataframe. Mediante `iloc` dice al dataframe que elimine `:` todas las filas y que me guarde desde la `1:` hasta el final.<jupyter_code>df = df_lmerged.iloc[:, 1:]
df



# Si intento hacer una operación de un subset de un dataframe con una columna del dataframe. 
# Tendré valores no numéricos.
df['t1'].iloc[::3]-df['t2']
# Para solucionar lo anterior puedo usar la función sub() que me resta y adicionalmente me permite usar el argumento fill_value, para rellenar ese NaN

df['t1'].iloc[::3].sub(df['t2'], fill_value = 1000)<jupyter_output><empty_output><jupyter_text>```+    add()-    sub(), subtract()*    mul(), multiply()/    truediv(), div(), divide()//   floordiv()%    mod()**   pow()```<jupyter_code># Puedo usar divisiones en columnas, al encontrarse con inf dice que  se encontró sobre una cantidad infonita.
df['t1']/df['t2']
# La función dot()... me permite hacer ua multiplicación de matrices entre dataframes.

df['t1'].dot(df['t1'])
# Mas ejemplos sobre la función dot.

# df = pd.DataFrame([[0, 1, -2, -1], [1, 1, 1, 1]])
# s = pd.Series([1, 1, 2, 1])
# df.dot(s)<jupyter_output><empty_output><jupyter_text>Funciones más complejas y lambdas<jupyter_code>def fun_1(x):
  y = x**2 + 1
  return y
fun_1(10)
np.arange(-5,6)
np.arange(-5,6).shape
fun_1(np.arange(-5,6))
df<jupyter_output><empty_output><jupyter_text>Funciones apply() Se usan en filas o columnas<jupyter_code># Si quiero aplicar a mi dataframe, especificamente a mis series de horas del dataframe toda la función que recién escribí.x**2+1

df['hour'].apply(fun_1)
def fun_2(x, a=1, b=0):
  y = x**2 + a*x + b
  return y
fun_2(10, a = 20, b= -100)
# Si la función que quiero aplciar a mi dataframe posee argumentos me valgo de la función args para decirle cuales serán. Cabe aclarar que los argumentos que está usando 
# son opcionales desde que sean llamados
df['hour'].apply(fun_2, args = (20, -100))
df['hour'].apply(fun_2, a =20, b= -100)
# Una forma mucho más rápida para no tener que definir la función es usar lambda.
df['hour'].apply(lambda x: x**2 + 1 )
# Una forma mucho más rápida para no tener que definir la función es usar lambda. Paso temperatura a Kelvin sumando mas 273

df['t1'].apply(lambda x: x+273)
# Puedo aplicar una función a todo el dataframe haciendo un promedio.

df.apply(lambda x: x.mean())
# Así le puedo escpecificar las columnas mediante ejes.
df.apply(lambda x: x.mean(), axis=1)
# Puedo usar tambien para desviaciones estaándara
df.apply(lambda x: x.std(), axis=1)
df.apply(lambda x: x['t1']-x['t2'], axis=1)
# Para aplciar un cambio a todo el mapa frame me permite operar a todos los valores individualmente. 

df.applymap(lambda x: x/1000)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10910815939278938, 'fraction_numerical': 0.020683111954459203, 'mean_word_length': 4.996587030716723, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 37, 'https://': 1, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '45597', 'license': 'MIT', 'n_tokens_mistral': 1977, 'n_tokens_neox': 1884, 'n_words': 628, 'path': 'NoteBooks/Curso de Análisis de datos/Depurando/Casos de estudio/Explorando Datasets - Londo Bike Sharing.ipynb', 'repo_name': 'Alejandro-sin/Learning_Notebooks', 'size': '5270'}