<jupyter_start><jupyter_text>Librerías: Pandashttps://pandas.pydata.org/El contenido de este tutorial está basado y fue adaptado del curso de pandas de Kaggle disponible en https://www.kaggle.com/learn/pandasmismo que tiene licencia open source Apache 2.0 http://www.apache.org/licenses/LICENSE-2.0 En esta parte vamos a aprender cómo seleccionar datos específicos del dataframe Comenzamos importando la librería y cargando el archivo que vamos a trabajar<jupyter_code>import pandas as pd
from pathlib import Path 
data_folder = Path("..") / "data"
wine_reviews_file = data_folder /"winemag-data-130k-v2.csv"
reviews = pd.read_csv(wine_reviews_file,index_col=0)

pd.set_option('max_rows', 5) # Esto para qué es?<jupyter_output><empty_output><jupyter_text>Accesos nativos<jupyter_code>reviews<jupyter_output><empty_output><jupyter_text>Por ejemplo si quiero acceder a la propiedad `country` del dataframe `reviews` se puede usar esta notación:<jupyter_code>reviews.country<jupyter_output><empty_output><jupyter_text>Pero también podemos accesar usando el operador índice (`[]`):<jupyter_code>reviews['country']<jupyter_output><empty_output><jupyter_text>Ambas son dos formas de seleccionar series de un DataFrame, ambas válidas, sin embargo el operador `[]` permite más flexibilidad en el nombre de las columnas, pudiendo usar caracteres reservados (e.g.  si tuviéramos una columna llamada `country providence` la notación de propiedad `reviews.country providence` no funciona. Seleccionar un elemento aún más específicoPodemos usar nuevamente la notación de índice, inmediatamente después de haber seleccionado la columna<jupyter_code>reviews['country'][0]
reviews.country[0]<jupyter_output><empty_output><jupyter_text>Indexing propio de pandasPandas tiene sus propios operadores de acceso `loc` and `iloc`. Ambos son primero renglón y luego columna (OJO! En python "nativo" es al revés!) Se supone que es mejor usar esto para operaciones más avanzadas. Selección basada en índiceConsiste en seleccionar datos basados en su posición numérica en el set de datos y se usa `iloc`.Trata al dataframe como si fuera una matriz y buscas los elementos usando su posición.Por ejemplo, para seleccionar el primer renglón en un DataFrame:<jupyter_code>reviews.iloc[0]<jupyter_output><empty_output><jupyter_text>Para obtener una columna con `iloc`:<jupyter_code>reviews.iloc[:, 0]<jupyter_output><empty_output><jupyter_text>El operador  `:` significa "todo" y también en combinación con otro código sirve para establecer un range de valores. Por ejemplo para seleccionar los renglones primero, segundo y tercero:<jupyter_code>reviews.iloc[:3, 0]<jupyter_output><empty_output><jupyter_text>O seleccionando el segundo y el tercero:<jupyter_code>reviews.iloc[1:3, 0]<jupyter_output><empty_output><jupyter_text>O también podemos indicarle qué renglones queremos mediante una lista:<jupyter_code>reviews.iloc[[0, 1, 2], 0]<jupyter_output><empty_output><jupyter_text>O también los últimos 5 renglones:<jupyter_code>reviews.iloc[-5:]<jupyter_output><empty_output><jupyter_text>2. Selección basada en etiquetaCon el operador `loc` es la etiqueta del índice y no la posición numérica lo que importa.Por ejemplo, para obtener la primer entrada en `reviews`, hacemos lo siguiente:<jupyter_code>reviews.loc[0,'country']
reviews.head()
reviews.loc[:, ['taster_name', 'taster_twitter_handle', 'points']]<jupyter_output><empty_output><jupyter_text>Eligiendo entre `loc` e `iloc``iloc` usa el esquema de indexing Python *stdlib*, donde el primer elemento del rango es incluido y el último es excluido. Ejemplo `0:10` selecciona  `0,...,9`. En cambio `loc`, indexa de forma "inclusiva" así que `0:10` seleccionará `0,...,10`.Si tenemos un dataframe con un indice que es una lista de  `0,...,1000`, al usar `df.iloc[0:1000]`nos regresará 1000 elementos, mientras que `df.loc[0:1000]` regresa 1001! Así que para tener 1000 elementos usando `loc`, se necesita colocar `df.loc[0:999]`.   Manipulando el índiceLa selección basada en etiquetas es poderosa debido a las etiquetas de los índices. El cuán podemos manipular acorde a nuestras necesidades.Por ejemplo con el método `set_index()` podemos lograr lo siguiete:<jupyter_code>reviews.set_index("title")<jupyter_output><empty_output><jupyter_text>Selección condicionalAhora, vamos a preguntarnos por selección basada en condiciones que cumplan los datos.Si queremos vinos producidos en Italia que sean mejores que el promedio ¿qué hacemos?Podemos empezar checando si un vino es Italiano o no:<jupyter_code>reviews.country == 'Italy'<jupyter_output><empty_output><jupyter_text>Con esta operación obtenemos una serie de `Verdaderos`/`Falsos` basados en la columna `country`. Esto, se puede usar dentro de loc, para obtener la información que queremos:<jupyter_code>vinos_italianos=reviews.loc[reviews.country == 'Italy']
vinos_italianos<jupyter_output><empty_output><jupyter_text>Si comparamos cuántos vinos Italianos hay respecto al total de los vinos del Dataframe original tenemos que:<jupyter_code>porcentaje_vinos_italianos = len(vinos_italianos)*100/len(reviews)<jupyter_output><empty_output><jupyter_text>Ahora bien, como los vinos se califican en una escala de 80 a 100, queremos saber cuáles tienen una calificación arriba de al menos 90 puntos. Usando la letra ampersand (`&`) unimos ambas condiciones:<jupyter_code>reviews.loc[(reviews.country == 'Italy') & (reviews.points >= 90)]<jupyter_output><empty_output><jupyter_text>Si ahora quisiéramos que se cumpliera alguna de las dos condiciones, es decir que sea Italiano o que tenga un puntaje arriba de 90 usamos este símbolo (`|`):<jupyter_code>reviews.loc[(reviews.country == 'Italy') | (reviews.points >= 90)]<jupyter_output><empty_output><jupyter_text>Selectores condicionales `isin`, `isnull`,`not null``isin` te permite seleccionar datos que estan dentro "Is in" de una lista de valores, por ejemplo, queremos seleccionar vinos que sean o de Italia o de Francia<jupyter_code>reviews.loc[reviews.country.isin(['Italy', 'France'])]<jupyter_output><empty_output><jupyter_text>`isnull` y `notnull`te permitirán seleccionar valores que son o no son vacíos `NaN`. Por ejemplo, para filtrar vinos que carecen de una etiqueta de precio<jupyter_code>reviews.loc[reviews.price.notnull()]<jupyter_output><empty_output><jupyter_text>Asignar datos a a un dataframeGoing the other way, assigning data to a DataFrame is easy. You can assign either a constant value:<jupyter_code>reviews['critic'] = 'everyone'
reviews['critic']<jupyter_output><empty_output><jupyter_text>Or with an iterable of values:<jupyter_code>reviews['index_backwards'] = range(len(reviews), 0, -1)
reviews['index_backwards']<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09168284306405854, 'fraction_numerical': 0.012990891443930118, 'mean_word_length': 7.3620474406991265, 'pattern_counts': {'":': 0, '<': 89, '<?xml version=': 0, '>': 91, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, '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': '22', 'dir': 'jupyter-structured-clean-dedup', 'id': '71562', 'license': 'CC-BY-4.0', 'n_tokens_mistral': 2432, 'n_tokens_neox': 2381, 'n_words': 679, 'path': 'notebooks/06-pandas_indexing-selecting-assigning.ipynb', 'repo_name': 'GeoLatinas/Intro-to-python', 'size': '6697'}