En mi opinión, la respuesta aceptada es confusa, ya que utiliza un DataFrame con solo valores faltantes. Tampoco me gusta el término basado en la posición .iloc
y, en cambio, prefiero la ubicación de enteros, ya que es mucho más descriptivo y exactamente lo que .iloc
significa. La palabra clave es INTEGER - .iloc
necesita INTEGERS.
Vea mi serie de blogs extremadamente detallada sobre la selección de subconjuntos para más
.ix está en desuso y es ambiguo y nunca debe usarse
Debido a que .ix
está en desuso, solo nos centraremos en las diferencias entre .loc
y .iloc
.
Antes de hablar sobre las diferencias, es importante comprender que los marcos de datos tienen etiquetas que ayudan a identificar cada columna y cada índice. Echemos un vistazo a un DataFrame de muestra:
df = pd.DataFrame({'age':[30, 2, 12, 4, 32, 33, 69],
'color':['blue', 'green', 'red', 'white', 'gray', 'black', 'red'],
'food':['Steak', 'Lamb', 'Mango', 'Apple', 'Cheese', 'Melon', 'Beans'],
'height':[165, 70, 120, 80, 180, 172, 150],
'score':[4.6, 8.3, 9.0, 3.3, 1.8, 9.5, 2.2],
'state':['NY', 'TX', 'FL', 'AL', 'AK', 'TX', 'TX']
},
index=['Jane', 'Nick', 'Aaron', 'Penelope', 'Dean', 'Christina', 'Cornelia'])
Todas las palabras en negrita son las etiquetas. Las etiquetas, age
, color
, food
, height
, score
y state
se utilizan para las columnas . Las otras etiquetas, Jane
, Nick
, Aaron
, Penelope
, Dean
, Christina
, Cornelia
se utilizan para el índice .
Las formas principales de seleccionar filas particulares en un DataFrame son con los indexadores .loc
y .iloc
. Cada uno de estos indexadores también se puede usar para seleccionar columnas simultáneamente, pero por ahora es más fácil centrarse en las filas. Además, cada uno de los indexadores utiliza un conjunto de corchetes que siguen inmediatamente a su nombre para realizar sus selecciones.
.loc selecciona datos solo por etiquetas
Primero hablaremos sobre el .loc
indexador que solo selecciona datos por las etiquetas de índice o columna. En nuestro DataFrame de muestra, proporcionamos nombres significativos como valores para el índice. Muchos DataFrames no tendrán nombres significativos y, por el contrario, solo usarán los enteros de 0 a n-1, donde n es la longitud del DataFrame.
Hay tres entradas diferentes que puede usar para .loc
- Una cuerda
- Una lista de cadenas
- Corte la notación utilizando cadenas como valores iniciales y finales
Seleccionar una sola fila con .loc con una cadena
Para seleccionar una sola fila de datos, coloque la etiqueta de índice dentro de los corchetes siguientes .loc
.
df.loc['Penelope']
Esto devuelve la fila de datos como una serie
age 4
color white
food Apple
height 80
score 3.3
state AL
Name: Penelope, dtype: object
Seleccionar varias filas con .loc con una lista de cadenas
df.loc[['Cornelia', 'Jane', 'Dean']]
Esto devuelve un DataFrame con las filas en el orden especificado en la lista:
Seleccionar varias filas con .loc con notación de corte
La notación de corte se define mediante valores de inicio, parada y paso. Al cortar por etiqueta, los pandas incluyen el valor de detención en el retorno. Los siguientes cortes de Aaron a Dean, inclusive. Su tamaño de paso no está definido explícitamente sino que está predeterminado en 1.
df.loc['Aaron':'Dean']
Los cortes complejos se pueden tomar de la misma manera que las listas de Python.
.iloc selecciona datos solo por ubicación entera
Pasemos ahora a .iloc
. Cada fila y columna de datos en un DataFrame tiene una ubicación entera que lo define. Esto se suma a la etiqueta que se muestra visualmente en la salida . La ubicación entera es simplemente el número de filas / columnas desde la parte superior / izquierda que comienza en 0.
Hay tres entradas diferentes que puede usar para .iloc
- Un entero
- Una lista de enteros
- Corte la notación usando enteros como valores de inicio y parada
Seleccionar una sola fila con .iloc con un entero
df.iloc[4]
Esto devuelve la quinta fila (ubicación entera 4) como una serie
age 32
color gray
food Cheese
height 180
score 1.8
state AK
Name: Dean, dtype: object
Seleccionar varias filas con .iloc con una lista de enteros
df.iloc[[2, -2]]
Esto devuelve un DataFrame de la tercera y la penúltima fila:
Selección de varias filas con .iloc con notación de corte
df.iloc[:5:3]
Selección simultánea de filas y columnas con .loc y .iloc
Una excelente habilidad de ambos .loc/.iloc
es su habilidad para seleccionar filas y columnas simultáneamente. En los ejemplos anteriores, todas las columnas fueron devueltas de cada selección. Podemos elegir columnas con los mismos tipos de entradas que para las filas. Simplemente necesitamos separar la selección de fila y columna con una coma .
Por ejemplo, podemos seleccionar las filas Jane y Dean con solo la altura de las columnas, la puntuación y el estado de esta manera:
df.loc[['Jane', 'Dean'], 'height':]
Esto usa una lista de etiquetas para las filas y la notación de corte para las columnas
Naturalmente, podemos hacer operaciones similares .iloc
usando solo enteros.
df.iloc[[1,4], 2]
Nick Lamb
Dean Cheese
Name: food, dtype: object
Selección simultánea con etiquetas y ubicación de enteros
.ix
se usó para hacer selecciones simultáneamente con etiquetas y ubicación de enteros, lo que fue útil pero confuso y ambiguo a veces y, afortunadamente, ha quedado en desuso. En el caso de que necesite hacer una selección con una combinación de etiquetas y ubicaciones de enteros, deberá realizar tanto las etiquetas de selección como las ubicaciones de enteros.
Por ejemplo, si queremos seleccionar filas Nick
y Cornelia
junto con las columnas 2 y 4, podríamos usar .loc
convirtiendo los enteros en etiquetas con lo siguiente:
col_names = df.columns[[2, 4]]
df.loc[['Nick', 'Cornelia'], col_names]
O, alternativamente, convierta las etiquetas de índice a enteros con el get_loc
método de índice.
labels = ['Nick', 'Cornelia']
index_ints = [df.index.get_loc(label) for label in labels]
df.iloc[index_ints, [2, 4]]
Selección booleana
El indexador .loc también puede hacer una selección booleana. Por ejemplo, si estamos interesados en encontrar todas las filas con una edad superior a 30 y devolver solo las columnas food
y score
, podemos hacer lo siguiente:
df.loc[df['age'] > 30, ['food', 'score']]
Puede replicar esto con, .iloc
pero no puede pasarle una serie booleana. Debe convertir la serie booleana en una matriz numpy como esta:
df.iloc[(df['age'] > 30).values, [2, 4]]
Seleccionar todas las filas
Es posible usar .loc/.iloc
solo para la selección de columnas. Puede seleccionar todas las filas utilizando dos puntos como este:
df.loc[:, 'color':'score':2]
El operador de indexación []
, también puede seleccionar filas y columnas, pero no simultáneamente.
La mayoría de las personas están familiarizadas con el propósito principal del operador de indexación de DataFrame, que es seleccionar columnas. Una cadena selecciona una sola columna como Serie y una lista de cadenas selecciona varias columnas como un Marco de datos.
df['food']
Jane Steak
Nick Lamb
Aaron Mango
Penelope Apple
Dean Cheese
Christina Melon
Cornelia Beans
Name: food, dtype: object
Usar una lista selecciona múltiples columnas
df[['food', 'score']]
Con lo que la gente está menos familiarizada es que, cuando se usa la notación de corte, la selección se realiza por etiquetas de fila o por ubicación entera. Esto es muy confuso y es algo que casi nunca uso, pero funciona.
df['Penelope':'Christina'] # slice rows by label
df[2:6:2] # slice rows by integer location
La especificidad de .loc/.iloc
para seleccionar filas es altamente preferida. El operador de indexación solo no puede seleccionar filas y columnas simultáneamente.
df[3:5, 'color']
TypeError: unhashable type: 'slice'