Visualización de dataframes, selección y asignación de datos
Índice de contenido
En primer lugar, haciendo uso de los conceptos aprendidos en la anterior lección, vamos a cargar unos datos en un DataFrame a partir de un archivo descargado del repositorio UCI de Machine Learning: https://archive.ics.uci.edu/ml/datasets/Adult
import pandas as pd
import numpy as np
file_path = "C:/Users/user/Desktop/adult.data"
col_names = ["age",
"workclass",
"fnlwgt",
"education",
"education-num",
"marital-status",
"occupation",
"relationship",
"race",
"sex",
"capital-gain",
"capital-loss",
"hours-per-week",
"native-country",
"income"]
df = pd.read_csv(filepath_or_buffer = file_path,
header = 0,
names = col_names)
df
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 50 | Self-emp-not-inc | 83311 | Bachelors | 13 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 0 | 0 | 13 | United-States | <=50K |
| 1 | 38 | Private | 215646 | HS-grad | 9 | Divorced | Handlers-cleaners | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
| 2 | 53 | Private | 234721 | 11th | 7 | Married-civ-spouse | Handlers-cleaners | Husband | Black | Male | 0 | 0 | 40 | United-States | <=50K |
| 3 | 28 | Private | 338409 | Bachelors | 13 | Married-civ-spouse | Prof-specialty | Wife | Black | Female | 0 | 0 | 40 | Cuba | <=50K |
| 4 | 37 | Private | 284582 | Masters | 14 | Married-civ-spouse | Exec-managerial | Wife | White | Female | 0 | 0 | 40 | United-States | <=50K |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 32555 | 27 | Private | 257302 | Assoc-acdm | 12 | Married-civ-spouse | Tech-support | Wife | White | Female | 0 | 0 | 38 | United-States | <=50K |
| 32556 | 40 | Private | 154374 | HS-grad | 9 | Married-civ-spouse | Machine-op-inspct | Husband | White | Male | 0 | 0 | 40 | United-States | >50K |
| 32557 | 58 | Private | 151910 | HS-grad | 9 | Widowed | Adm-clerical | Unmarried | White | Female | 0 | 0 | 40 | United-States | <=50K |
| 32558 | 22 | Private | 201490 | HS-grad | 9 | Never-married | Adm-clerical | Own-child | White | Male | 0 | 0 | 20 | United-States | <=50K |
| 32559 | 52 | Self-emp-inc | 287927 | HS-grad | 9 | Married-civ-spouse | Exec-managerial | Wife | White | Female | 15024 | 0 | 40 | United-States | >50K |
32560 rows × 15 columns
Visualización básica de DataFrames
df.head(): primeras filas
# df.head() nos muestra, por defecto, las primeras 5 filas del dataframe
df.head()
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 50 | Self-emp-not-inc | 83311 | Bachelors | 13 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 0 | 0 | 13 | United-States | <=50K |
| 1 | 38 | Private | 215646 | HS-grad | 9 | Divorced | Handlers-cleaners | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
| 2 | 53 | Private | 234721 | 11th | 7 | Married-civ-spouse | Handlers-cleaners | Husband | Black | Male | 0 | 0 | 40 | United-States | <=50K |
| 3 | 28 | Private | 338409 | Bachelors | 13 | Married-civ-spouse | Prof-specialty | Wife | Black | Female | 0 | 0 | 40 | Cuba | <=50K |
| 4 | 37 | Private | 284582 | Masters | 14 | Married-civ-spouse | Exec-managerial | Wife | White | Female | 0 | 0 | 40 | United-States | <=50K |
# Si quieremos ver más o menos de 5 filas, como por ejemplo 2, podemos especificarlo de la siguiente manera:
df.head(n=2)
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 50 | Self-emp-not-inc | 83311 | Bachelors | 13 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 0 | 0 | 13 | United-States | <=50K |
| 1 | 38 | Private | 215646 | HS-grad | 9 | Divorced | Handlers-cleaners | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
df.tail(): últimas filas
Funciona de forma idéntica a df.head(), pero mostrando las últimas filas en lugar de las primeras:
df.tail()
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 32555 | 27 | Private | 257302 | Assoc-acdm | 12 | Married-civ-spouse | Tech-support | Wife | White | Female | 0 | 0 | 38 | United-States | <=50K |
| 32556 | 40 | Private | 154374 | HS-grad | 9 | Married-civ-spouse | Machine-op-inspct | Husband | White | Male | 0 | 0 | 40 | United-States | >50K |
| 32557 | 58 | Private | 151910 | HS-grad | 9 | Widowed | Adm-clerical | Unmarried | White | Female | 0 | 0 | 40 | United-States | <=50K |
| 32558 | 22 | Private | 201490 | HS-grad | 9 | Never-married | Adm-clerical | Own-child | White | Male | 0 | 0 | 20 | United-States | <=50K |
| 32559 | 52 | Self-emp-inc | 287927 | HS-grad | 9 | Married-civ-spouse | Exec-managerial | Wife | White | Female | 15024 | 0 | 40 | United-States | >50K |
df.tail(n=2)
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 32558 | 22 | Private | 201490 | HS-grad | 9 | Never-married | Adm-clerical | Own-child | White | Male | 0 | 0 | 20 | United-States | <=50K |
| 32559 | 52 | Self-emp-inc | 287927 | HS-grad | 9 | Married-civ-spouse | Exec-managerial | Wife | White | Female | 15024 | 0 | 40 | United-States | >50K |
df.sample(): filas aleatorias
En este caso, por defecto solo se muestra una fila aleatoria, aunque también se puede especificar cualquier otro número para mostrar más filas.
df.sample()
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1941 | 24 | Local-gov | 249101 | HS-grad | 9 | Divorced | Protective-serv | Unmarried | Black | Female | 0 | 0 | 40 | United-States | <=50K |
df.sample(n = 5)
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 32037 | 52 | Private | 294991 | Bachelors | 13 | Married-civ-spouse | Prof-specialty | Husband | White | Male | 0 | 0 | 40 | United-States | >50K |
| 3507 | 37 | Private | 265038 | Some-college | 10 | Married-civ-spouse | Transport-moving | Husband | White | Male | 0 | 0 | 50 | United-States | <=50K |
| 807 | 64 | Private | 270333 | Bachelors | 13 | Married-civ-spouse | Prof-specialty | Husband | White | Male | 0 | 0 | 40 | United-States | >50K |
| 17249 | 25 | Private | 456618 | 7th-8th | 4 | Never-married | Machine-op-inspct | Unmarried | White | Male | 0 | 0 | 40 | El-Salvador | <=50K |
| 17770 | 54 | Private | 93605 | HS-grad | 9 | Married-civ-spouse | Sales | Husband | White | Male | 0 | 1848 | 40 | United-States | >50K |
df.sample(frac= 0.1)
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 22204 | 38 | Private | 201454 | Some-college | 10 | Divorced | Adm-clerical | Unmarried | White | Female | 0 | 0 | 40 | United-States | <=50K |
| 522 | 37 | Local-gov | 186035 | Some-college | 10 | Married-civ-spouse | Tech-support | Husband | White | Male | 0 | 0 | 45 | United-States | >50K |
| 22175 | 22 | Private | 137591 | Some-college | 10 | Never-married | Sales | Own-child | White | Male | 0 | 0 | 35 | United-States | <=50K |
| 13421 | 53 | Private | 366957 | Bachelors | 13 | Married-civ-spouse | Exec-managerial | Husband | Asian-Pac-Islander | Male | 99999 | 0 | 50 | India | >50K |
| 28741 | 41 | Private | 118721 | 12th | 8 | Divorced | Adm-clerical | Not-in-family | Amer-Indian-Eskimo | Male | 0 | 0 | 40 | United-States | <=50K |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 26171 | 59 | Self-emp-inc | 141326 | Assoc-voc | 11 | Divorced | Prof-specialty | Not-in-family | White | Male | 0 | 0 | 50 | United-States | >50K |
| 19613 | 46 | Private | 194431 | HS-grad | 9 | Never-married | Tech-support | Other-relative | White | Male | 0 | 0 | 40 | United-States | <=50K |
| 17313 | 76 | ? | 84755 | Some-college | 10 | Widowed | ? | Unmarried | White | Female | 0 | 0 | 40 | United-States | <=50K |
| 13896 | 24 | Private | 193920 | Masters | 14 | Never-married | Priv-house-serv | Not-in-family | White | Female | 0 | 0 | 45 | ? | <=50K |
| 20908 | 77 | Self-emp-not-inc | 71676 | Some-college | 10 | Widowed | Adm-clerical | Not-in-family | White | Female | 0 | 1944 | 1 | United-States | <=50K |
3256 rows × 15 columns
df.sample(n = 5, random_state=10)
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 11358 | 41 | Private | 134130 | Bachelors | 13 | Married-civ-spouse | Sales | Husband | White | Male | 0 | 0 | 50 | United-States | >50K |
| 10859 | 38 | Private | 107302 | Some-college | 10 | Married-civ-spouse | Sales | Husband | White | Male | 0 | 0 | 60 | United-States | >50K |
| 30948 | 24 | Private | 136687 | HS-grad | 9 | Separated | Machine-op-inspct | Unmarried | Other | Female | 0 | 0 | 40 | United-States | <=50K |
| 29811 | 35 | Self-emp-inc | 187053 | Bachelors | 13 | Separated | Prof-specialty | Not-in-family | White | Female | 0 | 0 | 50 | United-States | <=50K |
| 18408 | 69 | ? | 254834 | Bachelors | 13 | Married-civ-spouse | ? | Husband | White | Male | 10605 | 0 | 10 | United-States | >50K |
df.sample(n = 5, random_state=10)
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 11358 | 41 | Private | 134130 | Bachelors | 13 | Married-civ-spouse | Sales | Husband | White | Male | 0 | 0 | 50 | United-States | >50K |
| 10859 | 38 | Private | 107302 | Some-college | 10 | Married-civ-spouse | Sales | Husband | White | Male | 0 | 0 | 60 | United-States | >50K |
| 30948 | 24 | Private | 136687 | HS-grad | 9 | Separated | Machine-op-inspct | Unmarried | Other | Female | 0 | 0 | 40 | United-States | <=50K |
| 29811 | 35 | Self-emp-inc | 187053 | Bachelors | 13 | Separated | Prof-specialty | Not-in-family | White | Female | 0 | 0 | 50 | United-States | <=50K |
| 18408 | 69 | ? | 254834 | Bachelors | 13 | Married-civ-spouse | ? | Husband | White | Male | 10605 | 0 | 10 | United-States | >50K |
df.index: índice
En el DataFrame df, no especificamos ningún índice especial, así que se creó uno por defecto a partir de una secuencia de números enteros. Puedes verlo de esta manera:
df.index
RangeIndex(start=0, stop=32560, step=1)
df.index.values
array([ 0, 1, 2, ..., 32557, 32558, 32559], dtype=int64)
En efecto, el índice que pandas ha creado es un rango de números enteros consecutivos, desde 0 (incluido) hasta 23561 (sin incluir).
df.columns: nombres de las columnas
df.columns
Index(['age', 'workclass', 'fnlwgt', 'education', 'education-num',
'marital-status', 'occupation', 'relationship', 'race', 'sex',
'capital-gain', 'capital-loss', 'hours-per-week', 'native-country',
'income'],
dtype='object')
Selección de filas y columnas (indexación)
Casi todas las operaciones de procesamiento de datos implican seleccionar las columnas concretas sobre las que se desea trabajar, lo que se puede hacer de varias formas, ya sea con los métodos nativos del lenguaje Python o con los métodos de la librería pandas.
file_path = "C:/Users/user/Desktop/adult.data"
col_names = ["age",
"workclass",
"fnlwgt",
"education",
"education-num",
"marital-status",
"occupation",
"relationship",
"race",
"sex",
"capital-gain",
"capital-loss",
"hours-per-week",
"native-country",
"income"]
adult_data = pd.read_csv(filepath_or_buffer = file_path,
header = 0,
names = col_names)
adult_data
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 50 | NaN | 83311 | Bachelors | 13 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 0 | 0 | 13 | United-States | <=50K |
| 1 | 38 | Private | 215646 | HS-grad | 9 | Divorced | Handlers-cleaners | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
| 2 | 53 | Private | 234721 | 11th | 7 | Married-civ-spouse | Handlers-cleaners | Husband | Black | Male | 0 | 0 | 40 | United-States | <=50K |
| 3 | 28 | Private | 338409 | Bachelors | 13 | Married-civ-spouse | Prof-specialty | Wife | Black | Female | 0 | 0 | 40 | Cuba | <=50K |
| 4 | 37 | Private | 284582 | Masters | 14 | Married-civ-spouse | Exec-managerial | Wife | White | Female | 0 | 0 | 40 | United-States | <=50K |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 32555 | 27 | Private | 257302 | Assoc-acdm | 12 | Married-civ-spouse | Tech-support | Wife | White | Female | 0 | 0 | 38 | United-States | <=50K |
| 32556 | 40 | Private | 154374 | HS-grad | 9 | Married-civ-spouse | Machine-op-inspct | Husband | White | Male | 0 | 0 | 40 | United-States | >50K |
| 32557 | 58 | Private | 151910 | HS-grad | 9 | Widowed | Adm-clerical | Unmarried | White | Female | 0 | 0 | 40 | United-States | <=50K |
| 32558 | 22 | Private | 201490 | HS-grad | 9 | Never-married | Adm-clerical | Own-child | White | Male | 0 | 0 | 20 | United-States | <=50K |
| 32559 | 52 | Self-emp-inc | 287927 | HS-grad | 9 | Married-civ-spouse | Exec-managerial | Wife | White | Female | 15024 | 0 | 40 | United-States | >50K |
32560 rows × 15 columns
Métodos nativos del lenguaje Python
Selección de filas
adult_data[0:4]
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 50 | Self-emp-not-inc | 83311 | Bachelors | 13 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 0 | 0 | 13 | United-States | <=50K |
| 1 | 38 | Private | 215646 | HS-grad | 9 | Divorced | Handlers-cleaners | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
| 2 | 53 | Private | 234721 | 11th | 7 | Married-civ-spouse | Handlers-cleaners | Husband | Black | Male | 0 | 0 | 40 | United-States | <=50K |
| 3 | 28 | Private | 338409 | Bachelors | 13 | Married-civ-spouse | Prof-specialty | Wife | Black | Female | 0 | 0 | 40 | Cuba | <=50K |
adult_data[0:-2]
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 50 | Self-emp-not-inc | 83311 | Bachelors | 13 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 0 | 0 | 13 | United-States | <=50K |
| 1 | 38 | Private | 215646 | HS-grad | 9 | Divorced | Handlers-cleaners | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
| 2 | 53 | Private | 234721 | 11th | 7 | Married-civ-spouse | Handlers-cleaners | Husband | Black | Male | 0 | 0 | 40 | United-States | <=50K |
| 3 | 28 | Private | 338409 | Bachelors | 13 | Married-civ-spouse | Prof-specialty | Wife | Black | Female | 0 | 0 | 40 | Cuba | <=50K |
| 4 | 37 | Private | 284582 | Masters | 14 | Married-civ-spouse | Exec-managerial | Wife | White | Female | 0 | 0 | 40 | United-States | <=50K |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 32553 | 53 | Private | 321865 | Masters | 14 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 0 | 0 | 40 | United-States | >50K |
| 32554 | 22 | Private | 310152 | Some-college | 10 | Never-married | Protective-serv | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
| 32555 | 27 | Private | 257302 | Assoc-acdm | 12 | Married-civ-spouse | Tech-support | Wife | White | Female | 0 | 0 | 38 | United-States | <=50K |
| 32556 | 40 | Private | 154374 | HS-grad | 9 | Married-civ-spouse | Machine-op-inspct | Husband | White | Male | 0 | 0 | 40 | United-States | >50K |
| 32557 | 58 | Private | 151910 | HS-grad | 9 | Widowed | Adm-clerical | Unmarried | White | Female | 0 | 0 | 40 | United-States | <=50K |
32558 rows × 15 columns
adult_data[:3]
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 50 | Self-emp-not-inc | 83311 | Bachelors | 13 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 0 | 0 | 13 | United-States | <=50K |
| 1 | 38 | Private | 215646 | HS-grad | 9 | Divorced | Handlers-cleaners | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
| 2 | 53 | Private | 234721 | 11th | 7 | Married-civ-spouse | Handlers-cleaners | Husband | Black | Male | 0 | 0 | 40 | United-States | <=50K |
Selección de columnas
El lenguaje Python, ya de por sí, proporciona algunas maneras de indexar datos, como por ejemplo accediendo a una propiedad de un objeto como si de un atributo se tratara. Si quisiéramos acceder a la columna occupation del DataFrame anterior, podríamos hacerlo de la siguiente manera:
adult_data.occupation
0 Exec-managerial
1 Handlers-cleaners
2 Handlers-cleaners
3 Prof-specialty
4 Exec-managerial
...
32555 Tech-support
32556 Machine-op-inspct
32557 Adm-clerical
32558 Adm-clerical
32559 Exec-managerial
Name: occupation, Length: 32560, dtype: object
Por otro lado, de forma similar a como hacemos para acceder a los valores de un diccionario de Python, también podemos acceder a los valores de una columna usando el operador []:
adult_data["occupation"]
0 Exec-managerial
1 Handlers-cleaners
2 Handlers-cleaners
3 Prof-specialty
4 Exec-managerial
...
32555 Tech-support
32556 Machine-op-inspct
32557 Adm-clerical
32558 Adm-clerical
32559 Exec-managerial
Name: occupation, Length: 32560, dtype: object
Por tanto, los dos métodos anteriores permiten seleccionar una Serie concreta de un DataFrame. Ambos son igual de válidos, pero el operador de indexación [] tiene la gran ventaja de que permite nombres de columnas con caracteres especiales. Es decir, si queremos acceder a la columna hours-per-week:
- df.hours-per-week no funcionará (no sabe tratar los guiones, ni tampoco funcionaría si el nombre tuviera espacios en blanco).
- df[“hours-per-week”] sí funcionará.
Comprobémoslo:
adult_data.hours-per-week
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-29-3516cc3a2087> in <module>
----> 1 df.hours-per-week
~\anaconda3\envs\python-385\lib\site-packages\pandas\core\generic.py in __getattr__(self, name)
5134 if self._info_axis._can_hold_identifiers_and_holds_name(name):
5135 return self[name]
-> 5136 return object.__getattribute__(self, name)
5137
5138 def __setattr__(self, name: str, value) -> None:
AttributeError: 'DataFrame' object has no attribute 'hours'
adult_data["hours-per-week"]
0 13
1 40
2 40
3 40
4 40
..
32555 38
32556 40
32557 40
32558 20
32559 40
Name: hours-per-week, Length: 32560, dtype: int64
Si no solo queremos seleccionar una columna, sino un valor concreto dentro de esa columna, podemos acceder a él de la siguiente manera:
adult_data["hours-per-week"][32555]
38
Donde [1] indica la posición del valor dentro de la columna.
Métodos de pandas
Los métodos nativos de Python anteriores funcionan muy bien, pero la librería pandas tiene también sus propios métodos para seleccionar y acceder a columnas y valores concretos de un objeto.
adult_data
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 50 | NaN | 83311 | Bachelors | 13 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 0 | 0 | 13 | United-States | <=50K |
| 1 | 38 | Private | 215646 | HS-grad | 9 | Divorced | Handlers-cleaners | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
| 2 | 53 | Private | 234721 | 11th | 7 | Married-civ-spouse | Handlers-cleaners | Husband | Black | Male | 0 | 0 | 40 | United-States | <=50K |
| 3 | 28 | Private | 338409 | Bachelors | 13 | Married-civ-spouse | Prof-specialty | Wife | Black | Female | 0 | 0 | 40 | Cuba | <=50K |
| 4 | 37 | Private | 284582 | Masters | 14 | Married-civ-spouse | Exec-managerial | Wife | White | Female | 0 | 0 | 40 | United-States | <=50K |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 32555 | 27 | Private | 257302 | Assoc-acdm | 12 | Married-civ-spouse | Tech-support | Wife | White | Female | 0 | 0 | 38 | United-States | <=50K |
| 32556 | 40 | Private | 154374 | HS-grad | 9 | Married-civ-spouse | Machine-op-inspct | Husband | White | Male | 0 | 0 | 40 | United-States | >50K |
| 32557 | 58 | Private | 151910 | HS-grad | 9 | Widowed | Adm-clerical | Unmarried | White | Female | 0 | 0 | 40 | United-States | <=50K |
| 32558 | 22 | Private | 201490 | HS-grad | 9 | Never-married | Adm-clerical | Own-child | White | Male | 0 | 0 | 20 | United-States | <=50K |
| 32559 | 52 | Self-emp-inc | 287927 | HS-grad | 9 | Married-civ-spouse | Exec-managerial | Wife | White | Female | 15024 | 0 | 40 | United-States | >50K |
32560 rows × 15 columns
iloc: selección basada en posición
El primer método de pandas permite hacer selecciones basadas en un índice, es decir, en la posición numérica de un dato detro del conjunto de datos. Su sintaxis es data.iloc[filas,columnas], donde filas y columnas hacen referencia a la posición de las filas y columnas que se desea seleccionar.
Selección de filas
Tanto loc como iloc requieren indicar primero la fila y, en segundo lugar, la columna. Es decir, funcionan justo al revés que los métodos nativos de Python para indexación. Si no se especifican columnas concretas, se seleccionan todas las columnas de la fila. Por ejemplo, para seleccionar la primera fila del DataFrame con el que estamos trabajando:
adult_data.iloc[0]
age 50
workclass NaN
fnlwgt 83311
education Bachelors
education-num 13
marital-status Married-civ-spouse
occupation Exec-managerial
relationship Husband
race White
sex Male
capital-gain 0
capital-loss 0
hours-per-week 13
native-country United-States
income <=50K
Name: 0, dtype: object
adult_data.iloc[32555]
age 27
workclass Private
fnlwgt 257302
education Assoc-acdm
education-num 12
marital-status Married-civ-spouse
occupation Tech-support
relationship Wife
race White
sex Female
capital-gain 0
capital-loss 0
hours-per-week 38
native-country United-States
income <=50K
Name: 32555, dtype: object
adult_data[0:3]
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 50 | NaN | 83311 | Bachelors | 13 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 0 | 0 | 13 | United-States | <=50K |
| 1 | 38 | Private | 215646 | HS-grad | 9 | Divorced | Handlers-cleaners | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
| 2 | 53 | Private | 234721 | 11th | 7 | Married-civ-spouse | Handlers-cleaners | Husband | Black | Male | 0 | 0 | 40 | United-States | <=50K |
adult_data.iloc[0:3]
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 50 | NaN | 83311 | Bachelors | 13 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 0 | 0 | 13 | United-States | <=50K |
| 1 | 38 | Private | 215646 | HS-grad | 9 | Divorced | Handlers-cleaners | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
| 2 | 53 | Private | 234721 | 11th | 7 | Married-civ-spouse | Handlers-cleaners | Husband | Black | Male | 0 | 0 | 40 | United-States | <=50K |
Si se quiere seleccionar alguna fila empezando a contar desde el final del DataFrame, pueden usarse valores negativos:
adult_data.iloc[-1]
age 52
workclass Self-emp-inc
fnlwgt 287927
education HS-grad
education-num 9
marital-status Married-civ-spouse
occupation Exec-managerial
relationship Wife
race White
sex Female
capital-gain 15024
capital-loss 0
hours-per-week 40
native-country United-States
income >50K
Name: 32559, dtype: object
# Penúltima fila
adult_data.iloc[-2]
age 22
workclass Private
fnlwgt 201490
education HS-grad
education-num 9
marital-status Never-married
occupation Adm-clerical
relationship Own-child
race White
sex Male
capital-gain 0
capital-loss 0
hours-per-week 20
native-country United-States
income <=50K
Name: 32558, dtype: object
Selección de columnas
Para seleccionar una columna completa con iloc, hacemos lo siguiente:
# Primera columna
adult_data.iloc[:, 0]
0 50
1 38
2 53
3 28
4 37
..
32555 27
32556 40
32557 58
32558 22
32559 52
Name: age, Length: 32560, dtype: int64
# Última columna
adult_data.iloc[:, -1]
0 <=50K
1 <=50K
2 <=50K
3 <=50K
4 <=50K
...
32555 <=50K
32556 >50K
32557 <=50K
32558 <=50K
32559 >50K
Name: income, Length: 32560, dtype: object
Selección de filas y columnas
El operador “:”, por sí solo, ordena que se recojan “todos los valores”. Sin embargo, puede combinarse con otros selectores para referirse a un rango limitado de valores:
# Desde la primera fila (incluida) hasta la de índice 3 (sin incluir)
adult_data.iloc[0:3]
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 50 | NaN | 83311 | Bachelors | 13 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 0 | 0 | 13 | United-States | <=50K |
| 1 | 38 | Private | 215646 | HS-grad | 9 | Divorced | Handlers-cleaners | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
| 2 | 53 | Private | 234721 | 11th | 7 | Married-civ-spouse | Handlers-cleaners | Husband | Black | Male | 0 | 0 | 40 | United-States | <=50K |
# Desde la primera fila (incluida) hasta la fila de índice 3 (sin incluir), pertenecientes a la primera columna
adult_data.iloc[0:3, 0]
0 50
1 38
2 53
Name: age, dtype: int64
# Todas las filas de las columnas con posiciones 0-3 (la 3 sin incluir)
adult_data.iloc[:, 0:3]
| age | workclass | fnlwgt | |
|---|---|---|---|
| 0 | 50 | NaN | 83311 |
| 1 | 38 | Private | 215646 |
| 2 | 53 | Private | 234721 |
| 3 | 28 | Private | 338409 |
| 4 | 37 | Private | 284582 |
| ... | ... | ... | ... |
| 32555 | 27 | Private | 257302 |
| 32556 | 40 | Private | 154374 |
| 32557 | 58 | Private | 151910 |
| 32558 | 22 | Private | 201490 |
| 32559 | 52 | Self-emp-inc | 287927 |
32560 rows × 3 columns
# Desde la fila 1 (incluida) hasta la 3 (sin incluir), pertenecientes a la primera columna
adult_data.iloc[1:3, 0]
1 38
2 53
Name: age, dtype: int64
# Primera, segunda y tercera fila
adult_data.iloc[[0, 1, 2]]
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 50 | NaN | 83311 | Bachelors | 13 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 0 | 0 | 13 | United-States | <=50K |
| 1 | 38 | Private | 215646 | HS-grad | 9 | Divorced | Handlers-cleaners | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
| 2 | 53 | Private | 234721 | 11th | 7 | Married-civ-spouse | Handlers-cleaners | Husband | Black | Male | 0 | 0 | 40 | United-States | <=50K |
# Primera, segunda y tercera fila
adult_data.iloc[[0, 1, 2], :]
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 50 | NaN | 83311 | Bachelors | 13 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 0 | 0 | 13 | United-States | <=50K |
| 1 | 38 | Private | 215646 | HS-grad | 9 | Divorced | Handlers-cleaners | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
| 2 | 53 | Private | 234721 | 11th | 7 | Married-civ-spouse | Handlers-cleaners | Husband | Black | Male | 0 | 0 | 40 | United-States | <=50K |
# Las filas 0, 1 y 2 de la primera columna
adult_data.iloc[[0,1,2], 0]
0 50
1 38
2 53
Name: age, dtype: int64
# Todas las filas de las columnas 0, 2 y 4
adult_data.iloc[:, [0, 2, 4]]
| age | fnlwgt | education-num | |
|---|---|---|---|
| 0 | 50 | 83311 | 13 |
| 1 | 38 | 215646 | 9 |
| 2 | 53 | 234721 | 7 |
| 3 | 28 | 338409 | 13 |
| 4 | 37 | 284582 | 14 |
| ... | ... | ... | ... |
| 32555 | 27 | 257302 | 12 |
| 32556 | 40 | 154374 | 9 |
| 32557 | 58 | 151910 | 9 |
| 32558 | 22 | 201490 | 9 |
| 32559 | 52 | 287927 | 9 |
32560 rows × 3 columns
También es posible utilizar números negativos en la selección, lo que implica que se empezará a contar desde el final de los valores:
# Fila 5 de un dataset, empezando a contar desde el final
adult_data.iloc[-5]
age 27
workclass Private
fnlwgt 257302
education Assoc-acdm
education-num 12
marital-status Married-civ-spouse
occupation Tech-support
relationship Wife
race White
sex Female
capital-gain 0
capital-loss 0
hours-per-week 38
native-country United-States
income <=50K
Name: 32555, dtype: object
# Fila 5 de un dataset, empezando a contar desde el final
adult_data.iloc[-5, :]
age 27
workclass Private
fnlwgt 257302
education Assoc-acdm
education-num 12
marital-status Married-civ-spouse
occupation Tech-support
relationship Wife
race White
sex Female
capital-gain 0
capital-loss 0
hours-per-week 38
native-country United-States
income <=50K
Name: 32555, dtype: object
loc: selección basada en etiquetas
df = pd.DataFrame({"Columna1": 10,
"Columna2": 20,
"Columna3": 30},
index = ["Fila1", "Fila2", "Fila3"])
df
| Columna1 | Columna2 | Columna3 | |
|---|---|---|---|
| Fila1 | 10 | 20 | 30 |
| Fila2 | 10 | 20 | 30 |
| Fila3 | 10 | 20 | 30 |
El segundo enfoque de pandas consiste en la selección basada en las etiquetas de los valores, en lugar de su posición.
# Primer valor de la columna "education-num"
df.loc["Fila1", "Columna1"]
10
# Todas las filas de las columnas "education", "marital-status" y "relationship"
adult_data.loc[:, ["education", "marital-status", "relationship"]]
| education | marital-status | relationship | |
|---|---|---|---|
| 0 | Bachelors | Married-civ-spouse | Husband |
| 1 | HS-grad | Divorced | Not-in-family |
| 2 | 11th | Married-civ-spouse | Husband |
| 3 | Bachelors | Married-civ-spouse | Wife |
| 4 | Masters | Married-civ-spouse | Wife |
| ... | ... | ... | ... |
| 32555 | Assoc-acdm | Married-civ-spouse | Wife |
| 32556 | HS-grad | Married-civ-spouse | Husband |
| 32557 | HS-grad | Widowed | Unmarried |
| 32558 | HS-grad | Never-married | Own-child |
| 32559 | HS-grad | Married-civ-spouse | Wife |
32560 rows × 3 columns
# Primer valor de la columna "education"
adult_data.loc[0, "education"]
' Bachelors'
Como hemos visto, el método iloc icluye el primer elemento del rango pero excluye el último, es decir, 0:10 seleccionará los valores del 0 al 9, ambos incluidos. El método loc, sin embargo, incluye tanto el primer elemento del rango como el último. Por tanto, 0:10 seleccionará los valores del 0 al 10, ambos incluidos.
adult_data.loc[0:10, ["education", "marital-status", "relationship"]]
| education | marital-status | relationship | |
|---|---|---|---|
| 0 | Bachelors | Married-civ-spouse | Husband |
| 1 | HS-grad | Divorced | Not-in-family |
| 2 | 11th | Married-civ-spouse | Husband |
| 3 | Bachelors | Married-civ-spouse | Wife |
| 4 | Masters | Married-civ-spouse | Wife |
| 5 | 9th | Married-spouse-absent | Not-in-family |
| 6 | HS-grad | Married-civ-spouse | Husband |
| 7 | Masters | Never-married | Not-in-family |
| 8 | Bachelors | Married-civ-spouse | Husband |
| 9 | Some-college | Married-civ-spouse | Husband |
| 10 | Bachelors | Married-civ-spouse | Husband |
adult_data.iloc[0:10, :]
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 50 | NaN | 83311 | Bachelors | 13 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 0 | 0 | 13 | United-States | <=50K |
| 1 | 38 | Private | 215646 | HS-grad | 9 | Divorced | Handlers-cleaners | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
| 2 | 53 | Private | 234721 | 11th | 7 | Married-civ-spouse | Handlers-cleaners | Husband | Black | Male | 0 | 0 | 40 | United-States | <=50K |
| 3 | 28 | Private | 338409 | Bachelors | 13 | Married-civ-spouse | Prof-specialty | Wife | Black | Female | 0 | 0 | 40 | Cuba | <=50K |
| 4 | 37 | Private | 284582 | Masters | 14 | Married-civ-spouse | Exec-managerial | Wife | White | Female | 0 | 0 | 40 | United-States | <=50K |
| 5 | 49 | Private | 160187 | 9th | 5 | Married-spouse-absent | Other-service | Not-in-family | Black | Female | 0 | 0 | 16 | Jamaica | <=50K |
| 6 | 52 | Self-emp-not-inc | 209642 | HS-grad | 9 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 0 | 0 | 45 | United-States | >50K |
| 7 | 31 | Private | 45781 | Masters | 14 | Never-married | Prof-specialty | Not-in-family | White | Female | 14084 | 0 | 50 | United-States | >50K |
| 8 | 42 | Private | 159449 | Bachelors | 13 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 5178 | 0 | 40 | United-States | >50K |
| 9 | 37 | Private | 280464 | Some-college | 10 | Married-civ-spouse | Exec-managerial | Husband | Black | Male | 0 | 0 | 80 | United-States | >50K |
Selección basada en condiciones
El método loc de pandas no solo permite seleccionar filas y columnas por etiquetas, sino también en base a condiciones.
Imagina que estamos interesados en conocer los adultos del dataset que nunca se han casado y que, además trabajan 40 horas o más a la semana. En primer lugar, podríamos descubrir cuáles no se han casado nunca de la siguiente manera:
adult_data.head(20)
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 50 | NaN | 83311 | Bachelors | 13 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 0 | 0 | 13 | United-States | <=50K |
| 1 | 38 | Private | 215646 | HS-grad | 9 | Divorced | Handlers-cleaners | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
| 2 | 53 | Private | 234721 | 11th | 7 | Married-civ-spouse | Handlers-cleaners | Husband | Black | Male | 0 | 0 | 40 | United-States | <=50K |
| 3 | 28 | Private | 338409 | Bachelors | 13 | Married-civ-spouse | Prof-specialty | Wife | Black | Female | 0 | 0 | 40 | Cuba | <=50K |
| 4 | 37 | Private | 284582 | Masters | 14 | Married-civ-spouse | Exec-managerial | Wife | White | Female | 0 | 0 | 40 | United-States | <=50K |
| 5 | 49 | Private | 160187 | 9th | 5 | Married-spouse-absent | Other-service | Not-in-family | Black | Female | 0 | 0 | 16 | Jamaica | <=50K |
| 6 | 52 | Self-emp-not-inc | 209642 | HS-grad | 9 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 0 | 0 | 45 | United-States | >50K |
| 7 | 31 | Private | 45781 | Masters | 14 | Never-married | Prof-specialty | Not-in-family | White | Female | 14084 | 0 | 50 | United-States | >50K |
| 8 | 42 | Private | 159449 | Bachelors | 13 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 5178 | 0 | 40 | United-States | >50K |
| 9 | 37 | Private | 280464 | Some-college | 10 | Married-civ-spouse | Exec-managerial | Husband | Black | Male | 0 | 0 | 80 | United-States | >50K |
| 10 | 30 | State-gov | 141297 | Bachelors | 13 | Married-civ-spouse | Prof-specialty | Husband | Asian-Pac-Islander | Male | 0 | 0 | 40 | India | >50K |
| 11 | 23 | Private | 122272 | Bachelors | 13 | Never-married | Adm-clerical | Own-child | White | Female | 0 | 0 | 30 | United-States | <=50K |
| 12 | 32 | Private | 205019 | Assoc-acdm | 12 | Never-married | Sales | Not-in-family | Black | Male | 0 | 0 | 50 | United-States | <=50K |
| 13 | 40 | Private | 121772 | Assoc-voc | 11 | Married-civ-spouse | Craft-repair | Husband | Asian-Pac-Islander | Male | 0 | 0 | 40 | ? | >50K |
| 14 | 34 | Private | 245487 | 7th-8th | 4 | Married-civ-spouse | Transport-moving | Husband | Amer-Indian-Eskimo | Male | 0 | 0 | 45 | Mexico | <=50K |
| 15 | 25 | Self-emp-not-inc | 176756 | HS-grad | 9 | Never-married | Farming-fishing | Own-child | White | Male | 0 | 0 | 35 | United-States | <=50K |
| 16 | 32 | Private | 186824 | HS-grad | 9 | Never-married | Machine-op-inspct | Unmarried | White | Male | 0 | 0 | 40 | United-States | <=50K |
| 17 | 38 | Private | 28887 | 11th | 7 | Married-civ-spouse | Sales | Husband | White | Male | 0 | 0 | 50 | United-States | <=50K |
| 18 | 43 | Self-emp-not-inc | 292175 | Masters | 14 | Divorced | Exec-managerial | Unmarried | White | Female | 0 | 0 | 45 | United-States | >50K |
| 19 | 40 | Private | 193524 | Doctorate | 16 | Married-civ-spouse | Prof-specialty | Husband | White | Male | 0 | 0 | 60 | United-States | >50K |
adult_data.loc[:, "marital-status"] == "Never-married"
0 False
1 False
2 False
3 False
4 False
...
32555 False
32556 False
32557 False
32558 False
32559 False
Name: marital-status, Length: 32560, dtype: bool
Esta operación produce una Serie con valores True/False en función de si la propiedad “marital-status” coincide con “Never-married” o no. Si introducimos esta operación en un loc, solo estaremos seleccionando los datos que cumplan la condición:
adult_data.loc[adult_data.loc[:, "marital-status"] == " Never-married"]
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 7 | 31 | Private | 45781 | Masters | 14 | Never-married | Prof-specialty | Not-in-family | White | Female | 14084 | 0 | 50 | United-States | >50K |
| 11 | 23 | Private | 122272 | Bachelors | 13 | Never-married | Adm-clerical | Own-child | White | Female | 0 | 0 | 30 | United-States | <=50K |
| 12 | 32 | Private | 205019 | Assoc-acdm | 12 | Never-married | Sales | Not-in-family | Black | Male | 0 | 0 | 50 | United-States | <=50K |
| 15 | 25 | Self-emp-not-inc | 176756 | HS-grad | 9 | Never-married | Farming-fishing | Own-child | White | Male | 0 | 0 | 35 | United-States | <=50K |
| 16 | 32 | Private | 186824 | HS-grad | 9 | Never-married | Machine-op-inspct | Unmarried | White | Male | 0 | 0 | 40 | United-States | <=50K |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 32536 | 30 | Private | 345898 | HS-grad | 9 | Never-married | Craft-repair | Not-in-family | Black | Male | 0 | 0 | 46 | United-States | <=50K |
| 32547 | 65 | Self-emp-not-inc | 99359 | Prof-school | 15 | Never-married | Prof-specialty | Not-in-family | White | Male | 1086 | 0 | 60 | United-States | <=50K |
| 32552 | 32 | Private | 116138 | Masters | 14 | Never-married | Tech-support | Not-in-family | Asian-Pac-Islander | Male | 0 | 0 | 11 | Taiwan | <=50K |
| 32554 | 22 | Private | 310152 | Some-college | 10 | Never-married | Protective-serv | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
| 32558 | 22 | Private | 201490 | HS-grad | 9 | Never-married | Adm-clerical | Own-child | White | Male | 0 | 0 | 20 | United-States | <=50K |
10682 rows × 15 columns
# La celda anterior devuelve un dataframe vacío, ¿por qué?
# Si aplicamos un unique(), vemos que ' Never-married' tiene un espacio en primera posición
adult_data.loc[:, "marital-status"].unique()
array([' Married-civ-spouse', ' Divorced', ' Married-spouse-absent',
' Never-married', ' Separated', ' Married-AF-spouse', ' Widowed'],
dtype=object)
Hasta aquí, solo hemos seleccionado los adultos que no han estado casados, pero no aquellos que trabajan 40h o más a la semana.
adult_data.loc[(adult_data.loc[:, "marital-status"] == " Never-married") &
(adult_data.loc[:, "hours-per-week"] >= 40)]
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 7 | 31 | Private | 45781 | Masters | 14 | Never-married | Prof-specialty | Not-in-family | White | Female | 14084 | 0 | 50 | United-States | >50K |
| 12 | 32 | Private | 205019 | Assoc-acdm | 12 | Never-married | Sales | Not-in-family | Black | Male | 0 | 0 | 50 | United-States | <=50K |
| 16 | 32 | Private | 186824 | HS-grad | 9 | Never-married | Machine-op-inspct | Unmarried | White | Male | 0 | 0 | 40 | United-States | <=50K |
| 25 | 19 | Private | 168294 | HS-grad | 9 | Never-married | Craft-repair | Own-child | White | Male | 0 | 0 | 40 | United-States | <=50K |
| 29 | 23 | Local-gov | 190709 | Assoc-acdm | 12 | Never-married | Protective-serv | Not-in-family | White | Male | 0 | 0 | 52 | United-States | <=50K |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 32530 | 30 | ? | 33811 | Bachelors | 13 | Never-married | ? | Not-in-family | Asian-Pac-Islander | Female | 0 | 0 | 99 | United-States | <=50K |
| 32535 | 34 | Private | 160216 | Bachelors | 13 | Never-married | Exec-managerial | Not-in-family | White | Female | 0 | 0 | 55 | United-States | >50K |
| 32536 | 30 | Private | 345898 | HS-grad | 9 | Never-married | Craft-repair | Not-in-family | Black | Male | 0 | 0 | 46 | United-States | <=50K |
| 32547 | 65 | Self-emp-not-inc | 99359 | Prof-school | 15 | Never-married | Prof-specialty | Not-in-family | White | Male | 1086 | 0 | 60 | United-States | <=50K |
| 32554 | 22 | Private | 310152 | Some-college | 10 | Never-married | Protective-serv | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
6872 rows × 15 columns
Imagina ahora que queremos conocer los adultos que no han estado casados o que trabajan 40h o más a la semana.
adult_data.loc[(adult_data.loc[:, "marital-status"] == " Never-married") |
(adult_data.loc[:, "hours-per-week"] >= 40)]
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 38 | Private | 215646 | HS-grad | 9 | Divorced | Handlers-cleaners | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
| 2 | 53 | Private | 234721 | 11th | 7 | Married-civ-spouse | Handlers-cleaners | Husband | Black | Male | 0 | 0 | 40 | United-States | <=50K |
| 3 | 28 | Private | 338409 | Bachelors | 13 | Married-civ-spouse | Prof-specialty | Wife | Black | Female | 0 | 0 | 40 | Cuba | <=50K |
| 4 | 37 | Private | 284582 | Masters | 14 | Married-civ-spouse | Exec-managerial | Wife | White | Female | 0 | 0 | 40 | United-States | <=50K |
| 6 | 52 | Self-emp-not-inc | 209642 | HS-grad | 9 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 0 | 0 | 45 | United-States | >50K |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 32554 | 22 | Private | 310152 | Some-college | 10 | Never-married | Protective-serv | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
| 32556 | 40 | Private | 154374 | HS-grad | 9 | Married-civ-spouse | Machine-op-inspct | Husband | White | Male | 0 | 0 | 40 | United-States | >50K |
| 32557 | 58 | Private | 151910 | HS-grad | 9 | Widowed | Adm-clerical | Unmarried | White | Female | 0 | 0 | 40 | United-States | <=50K |
| 32558 | 22 | Private | 201490 | HS-grad | 9 | Never-married | Adm-clerical | Own-child | White | Male | 0 | 0 | 20 | United-States | <=50K |
| 32559 | 52 | Self-emp-inc | 287927 | HS-grad | 9 | Married-civ-spouse | Exec-managerial | Wife | White | Female | 15024 | 0 | 40 | United-States | >50K |
28607 rows × 15 columns
adult_data.loc[:, "marital-status"]
0 Married-civ-spouse
1 Divorced
2 Married-civ-spouse
3 Married-civ-spouse
4 Married-civ-spouse
...
32555 Married-civ-spouse
32556 Married-civ-spouse
32557 Widowed
32558 Never-married
32559 Married-civ-spouse
Name: marital-status, Length: 32560, dtype: object
adult_data["marital-status"]
0 Married-civ-spouse
1 Divorced
2 Married-civ-spouse
3 Married-civ-spouse
4 Married-civ-spouse
...
32555 Married-civ-spouse
32556 Married-civ-spouse
32557 Widowed
32558 Never-married
32559 Married-civ-spouse
Name: marital-status, Length: 32560, dtype: object
adult_data.loc[(adult_data.loc[:, "marital-status"] == " Never-married") |
(adult_data.loc[:, "hours-per-week"] >= 40)]
adult_data.loc[(adult_data["marital-status"] == " Never-married") |
(adult_data["hours-per-week"] >= 40)]
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 38 | Private | 215646 | HS-grad | 9 | Divorced | Handlers-cleaners | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
| 2 | 53 | Private | 234721 | 11th | 7 | Married-civ-spouse | Handlers-cleaners | Husband | Black | Male | 0 | 0 | 40 | United-States | <=50K |
| 3 | 28 | Private | 338409 | Bachelors | 13 | Married-civ-spouse | Prof-specialty | Wife | Black | Female | 0 | 0 | 40 | Cuba | <=50K |
| 4 | 37 | Private | 284582 | Masters | 14 | Married-civ-spouse | Exec-managerial | Wife | White | Female | 0 | 0 | 40 | United-States | <=50K |
| 6 | 52 | Self-emp-not-inc | 209642 | HS-grad | 9 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 0 | 0 | 45 | United-States | >50K |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 32554 | 22 | Private | 310152 | Some-college | 10 | Never-married | Protective-serv | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
| 32556 | 40 | Private | 154374 | HS-grad | 9 | Married-civ-spouse | Machine-op-inspct | Husband | White | Male | 0 | 0 | 40 | United-States | >50K |
| 32557 | 58 | Private | 151910 | HS-grad | 9 | Widowed | Adm-clerical | Unmarried | White | Female | 0 | 0 | 40 | United-States | <=50K |
| 32558 | 22 | Private | 201490 | HS-grad | 9 | Never-married | Adm-clerical | Own-child | White | Male | 0 | 0 | 20 | United-States | <=50K |
| 32559 | 52 | Self-emp-inc | 287927 | HS-grad | 9 | Married-civ-spouse | Exec-managerial | Wife | White | Female | 15024 | 0 | 40 | United-States | >50K |
28607 rows × 15 columns
# Métodos nativos de Python
adult_data[(adult_data["marital-status"] == " Never-married") |
(adult_data["hours-per-week"] >= 40)]
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 38 | Private | 215646 | HS-grad | 9 | Divorced | Handlers-cleaners | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
| 2 | 53 | Private | 234721 | 11th | 7 | Married-civ-spouse | Handlers-cleaners | Husband | Black | Male | 0 | 0 | 40 | United-States | <=50K |
| 3 | 28 | Private | 338409 | Bachelors | 13 | Married-civ-spouse | Prof-specialty | Wife | Black | Female | 0 | 0 | 40 | Cuba | <=50K |
| 4 | 37 | Private | 284582 | Masters | 14 | Married-civ-spouse | Exec-managerial | Wife | White | Female | 0 | 0 | 40 | United-States | <=50K |
| 6 | 52 | Self-emp-not-inc | 209642 | HS-grad | 9 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 0 | 0 | 45 | United-States | >50K |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 32554 | 22 | Private | 310152 | Some-college | 10 | Never-married | Protective-serv | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
| 32556 | 40 | Private | 154374 | HS-grad | 9 | Married-civ-spouse | Machine-op-inspct | Husband | White | Male | 0 | 0 | 40 | United-States | >50K |
| 32557 | 58 | Private | 151910 | HS-grad | 9 | Widowed | Adm-clerical | Unmarried | White | Female | 0 | 0 | 40 | United-States | <=50K |
| 32558 | 22 | Private | 201490 | HS-grad | 9 | Never-married | Adm-clerical | Own-child | White | Male | 0 | 0 | 20 | United-States | <=50K |
| 32559 | 52 | Self-emp-inc | 287927 | HS-grad | 9 | Married-civ-spouse | Exec-managerial | Wife | White | Female | 15024 | 0 | 40 | United-States | >50K |
28607 rows × 15 columns
Pandas incluye también unos cuantos selectores específicos muy útiles, entre los cuales destaca isin. Este operador permite seleccionar los datos cuyos valores están dentro de una lista especificada. Por ejemplo, podríamos seleccionar los adultos que tiene nivel educativo “Bachelors” (como una licenciatura) o “Masters”:
value_list = [" Bachelors", " Masters"]
value_list
[' Bachelors', ' Masters']
# Antes de nada, vamos a asegurarnos de cómo están escritas ambas categorías en los datos
adult_data.loc[:, "education"].isin(value_list)
0 True
1 False
2 False
3 True
4 True
...
32555 False
32556 False
32557 False
32558 False
32559 False
Name: education, Length: 32560, dtype: bool
adult_data.loc[adult_data.loc[:, "education"].isin(value_list)]
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 50 | NaN | 83311 | Bachelors | 13 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 0 | 0 | 13 | United-States | <=50K |
| 3 | 28 | Private | 338409 | Bachelors | 13 | Married-civ-spouse | Prof-specialty | Wife | Black | Female | 0 | 0 | 40 | Cuba | <=50K |
| 4 | 37 | Private | 284582 | Masters | 14 | Married-civ-spouse | Exec-managerial | Wife | White | Female | 0 | 0 | 40 | United-States | <=50K |
| 7 | 31 | Private | 45781 | Masters | 14 | Never-married | Prof-specialty | Not-in-family | White | Female | 14084 | 0 | 50 | United-States | >50K |
| 8 | 42 | Private | 159449 | Bachelors | 13 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 5178 | 0 | 40 | United-States | >50K |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 32535 | 34 | Private | 160216 | Bachelors | 13 | Never-married | Exec-managerial | Not-in-family | White | Female | 0 | 0 | 55 | United-States | >50K |
| 32537 | 38 | Private | 139180 | Bachelors | 13 | Divorced | Prof-specialty | Unmarried | Black | Female | 15020 | 0 | 45 | United-States | >50K |
| 32543 | 31 | Private | 199655 | Masters | 14 | Divorced | Other-service | Not-in-family | Other | Female | 0 | 0 | 30 | United-States | <=50K |
| 32552 | 32 | Private | 116138 | Masters | 14 | Never-married | Tech-support | Not-in-family | Asian-Pac-Islander | Male | 0 | 0 | 11 | Taiwan | <=50K |
| 32553 | 53 | Private | 321865 | Masters | 14 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 0 | 0 | 40 | United-States | >50K |
7077 rows × 15 columns
adult_data.loc[:, "education"].unique()
array([' Bachelors', ' HS-grad', ' 11th', ' Masters', ' 9th',
' Some-college', ' Assoc-acdm', ' Assoc-voc', ' 7th-8th',
' Doctorate', ' Prof-school', ' 5th-6th', ' 10th', ' 1st-4th',
' Preschool', ' 12th'], dtype=object)
Asignación de datos
adult_data.head(3)
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 50 | NaN | 83311 | Bachelors | 13 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 0 | 0 | 13 | United-States | <=50K |
| 1 | 38 | Private | 215646 | HS-grad | 9 | Divorced | Handlers-cleaners | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
| 2 | 53 | Private | 234721 | 11th | 7 | Married-civ-spouse | Handlers-cleaners | Husband | Black | Male | 0 | 0 | 40 | United-States | <=50K |
Asignar datos a un DataFrame es muy sencillo, ya sea un valor constante o un conjunto de valores:
adult_data.loc[:, "education-num"] = "valor_constante"
adult_data.occupation = "occupation"
adult_data["marital-status"] = "estado"
adult_data["relationship"] = range(len(adult_data))
# adult_data["relationship"] = [10, 11, -5 , 3 ...]
adult_data["marital-status"] = adult_data["occupation"]
adult_data.loc[adult_data["education"] == " Bachelors", "marital-status"] = "X"
adult_data.loc[adult_data["education"] == " HS-grad", ["marital-status", "race"]] = "Y", "Z"
adult_data
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 50 | NaN | 83311 | Bachelors | valor_constante | X | occupation | 0 | White | Male | 0 | 0 | 13 | United-States | <=50K |
| 1 | 38 | Private | 215646 | HS-grad | valor_constante | Y | occupation | 1 | Z | Male | 0 | 0 | 40 | United-States | <=50K |
| 2 | 53 | Private | 234721 | 11th | valor_constante | occupation | occupation | 2 | Black | Male | 0 | 0 | 40 | United-States | <=50K |
| 3 | 28 | Private | 338409 | Bachelors | valor_constante | X | occupation | 3 | Black | Female | 0 | 0 | 40 | Cuba | <=50K |
| 4 | 37 | Private | 284582 | Masters | valor_constante | occupation | occupation | 4 | White | Female | 0 | 0 | 40 | United-States | <=50K |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 32555 | 27 | Private | 257302 | Assoc-acdm | valor_constante | occupation | occupation | 32555 | White | Female | 0 | 0 | 38 | United-States | <=50K |
| 32556 | 40 | Private | 154374 | HS-grad | valor_constante | Y | occupation | 32556 | Z | Male | 0 | 0 | 40 | United-States | >50K |
| 32557 | 58 | Private | 151910 | HS-grad | valor_constante | Y | occupation | 32557 | Z | Female | 0 | 0 | 40 | United-States | <=50K |
| 32558 | 22 | Private | 201490 | HS-grad | valor_constante | Y | occupation | 32558 | Z | Male | 0 | 0 | 20 | United-States | <=50K |
| 32559 | 52 | Self-emp-inc | 287927 | HS-grad | valor_constante | Y | occupation | 32559 | Z | Female | 15024 | 0 | 40 | United-States | >50K |
32560 rows × 15 columns
Como hemos visto, si la columna existe, se sobreescriben sus valores con el que le hayamos asignado. Si no existe, se crea una nueva columna:
adult_data["new_column"] = "New"
adult_data.loc[adult_data["sex"] == " Male", "nueva_columna"] = "M"
adult_data.loc[adult_data["sex"] != " Male", "nueva_columna2"] = "F"
adult_data["sex"].unique()
array([' Male', ' Female'], dtype=object)
adult_data
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | new_column | nueva_columna | nueva_columna2 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 50 | NaN | 83311 | Bachelors | valor_constante | X | occupation | 0 | White | Male | 0 | 0 | 13 | United-States | <=50K | New | M | NaN |
| 1 | 38 | Private | 215646 | HS-grad | valor_constante | Y | occupation | 1 | Z | Male | 0 | 0 | 40 | United-States | <=50K | New | M | NaN |
| 2 | 53 | Private | 234721 | 11th | valor_constante | occupation | occupation | 2 | Black | Male | 0 | 0 | 40 | United-States | <=50K | New | M | NaN |
| 3 | 28 | Private | 338409 | Bachelors | valor_constante | X | occupation | 3 | Black | Female | 0 | 0 | 40 | Cuba | <=50K | New | NaN | F |
| 4 | 37 | Private | 284582 | Masters | valor_constante | occupation | occupation | 4 | White | Female | 0 | 0 | 40 | United-States | <=50K | New | NaN | F |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 32555 | 27 | Private | 257302 | Assoc-acdm | valor_constante | occupation | occupation | 32555 | White | Female | 0 | 0 | 38 | United-States | <=50K | New | NaN | F |
| 32556 | 40 | Private | 154374 | HS-grad | valor_constante | Y | occupation | 32556 | Z | Male | 0 | 0 | 40 | United-States | >50K | New | M | NaN |
| 32557 | 58 | Private | 151910 | HS-grad | valor_constante | Y | occupation | 32557 | Z | Female | 0 | 0 | 40 | United-States | <=50K | New | NaN | F |
| 32558 | 22 | Private | 201490 | HS-grad | valor_constante | Y | occupation | 32558 | Z | Male | 0 | 0 | 20 | United-States | <=50K | New | M | NaN |
| 32559 | 52 | Self-emp-inc | 287927 | HS-grad | valor_constante | Y | occupation | 32559 | Z | Female | 15024 | 0 | 40 | United-States | >50K | New | NaN | F |
32560 rows × 18 columns
Manipulación del índice
Existe un método de pandas, set_index(), que permite establecer como índice el que nosotros queramos, como por ejemplo una columna:
adult_data
| age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | income | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 50 | NaN | 83311 | Bachelors | 13 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 0 | 0 | 13 | United-States | <=50K |
| 1 | 38 | Private | 215646 | HS-grad | 9 | Divorced | Handlers-cleaners | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
| 2 | 53 | Private | 234721 | 11th | 7 | Married-civ-spouse | Handlers-cleaners | Husband | Black | Male | 0 | 0 | 40 | United-States | <=50K |
| 3 | 28 | Private | 338409 | Bachelors | 13 | Married-civ-spouse | Prof-specialty | Wife | Black | Female | 0 | 0 | 40 | Cuba | <=50K |
| 4 | 37 | Private | 284582 | Masters | 14 | Married-civ-spouse | Exec-managerial | Wife | White | Female | 0 | 0 | 40 | United-States | <=50K |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 32555 | 27 | Private | 257302 | Assoc-acdm | 12 | Married-civ-spouse | Tech-support | Wife | White | Female | 0 | 0 | 38 | United-States | <=50K |
| 32556 | 40 | Private | 154374 | HS-grad | 9 | Married-civ-spouse | Machine-op-inspct | Husband | White | Male | 0 | 0 | 40 | United-States | >50K |
| 32557 | 58 | Private | 151910 | HS-grad | 9 | Widowed | Adm-clerical | Unmarried | White | Female | 0 | 0 | 40 | United-States | <=50K |
| 32558 | 22 | Private | 201490 | HS-grad | 9 | Never-married | Adm-clerical | Own-child | White | Male | 0 | 0 | 20 | United-States | <=50K |
| 32559 | 52 | Self-emp-inc | 287927 | HS-grad | 9 | Married-civ-spouse | Exec-managerial | Wife | White | Female | 15024 | 0 | 40 | United-States | >50K |
32560 rows × 15 columns
df = pd.DataFrame({"Columna1": [10, 20, 30],
"Columna2": [40, 50, 60],
"Columna3": 30},
index = ["Fila1", "Fila2", "Fila3"])
df
| Columna1 | Columna2 | Columna3 | |
|---|---|---|---|
| Fila1 | 10 | 40 | 30 |
| Fila2 | 20 | 50 | 30 |
| Fila3 | 30 | 60 | 30 |
nuevo_indice = ["Id1", "Id2", "Id3"]
nuevo_indice
['Id1', 'Id2', 'Id3']
df.set_index(nuevo_indice)
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-8-d4ffeb50a63e> in <module>
----> 1 df.set_index(nuevo_indice)
~\anaconda3\envs\python-385\lib\site-packages\pandas\core\frame.py in set_index(self, keys, drop, append, inplace, verify_integrity)
4548
4549 if missing:
-> 4550 raise KeyError(f"None of {missing} are in the columns")
4551
4552 if inplace:
KeyError: "None of ['Id1', 'Id2', 'Id3'] are in the columns"
nuevo_indice_arr = np.array(["Id1", "Id2", "Id3"])
nuevo_indice_arr
array(['Id1', 'Id2', 'Id3'], dtype='<U3')
df.set_index(nuevo_indice_arr)
| Columna1 | Columna2 | Columna3 | |
|---|---|---|---|
| Id1 | 10 | 40 | 30 |
| Id2 | 20 | 50 | 30 |
| Id3 | 30 | 60 | 30 |
df
| Columna1 | Columna2 | Columna3 | |
|---|---|---|---|
| Fila1 | 10 | 40 | 30 |
| Fila2 | 20 | 50 | 30 |
| Fila3 | 30 | 60 | 30 |
# Primera opción para conservar el resultado
df.set_index(nuevo_indice_arr, inplace=True)
df
| Columna1 | Columna2 | Columna3 | |
|---|---|---|---|
| Id1 | 10 | 40 | 30 |
| Id2 | 20 | 50 | 30 |
| Id3 | 30 | 60 | 30 |
# Primera opción para conservar el resultado
df = df.set_index(np.array(["i1", "i2", "i3"]), inplace=False)
df
| Columna1 | Columna2 | Columna3 | |
|---|---|---|---|
| i1 | 10 | 40 | 30 |
| i2 | 20 | 50 | 30 |
| i3 | 30 | 60 | 30 |
df.set_index("Columna3", inplace=True)
df
| Columna1 | Columna2 | |
|---|---|---|
| Columna3 | ||
| 30 | 10 | 40 |
| 30 | 20 | 50 |
| 30 | 30 | 60 |
df["Columna4"] = [40, 40, 40]
df
| Columna1 | Columna2 | Columna4 | |
|---|---|---|---|
| Columna3 | |||
| 30 | 10 | 40 | 40 |
| 30 | 20 | 50 | 40 |
| 30 | 30 | 60 | 40 |
df.set_index("Columna4", inplace=True, verify_integrity=True)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-20-93462f2e4f72> in <module>
----> 1 df.set_index("Columna4", inplace=True, verify_integrity=True)
~\anaconda3\envs\python-385\lib\site-packages\pandas\core\frame.py in set_index(self, keys, drop, append, inplace, verify_integrity)
4600 if verify_integrity and not index.is_unique:
4601 duplicates = index[index.duplicated()].unique()
-> 4602 raise ValueError(f"Index has duplicate keys: {duplicates}")
4603
4604 # use set to handle duplicate column names gracefully in case of drop
ValueError: Index has duplicate keys: Int64Index([40], dtype='int64', name='Columna4')
df.index
Int64Index([30, 30, 30], dtype='int64', name='Columna3')
df.index.values
array([30, 30, 30], dtype=int64)
df.index.to_list()
[30, 30, 30]
