Python: Pandas Series – ¿Por qué usar loc?

¿Por qué usamos ‘loc’ para los marcos de datos de pandas? Parece que el siguiente código con o sin usar loc comstack y se ejecuta a una velocidad similar

%timeit df_user1 = df.loc[df.user_id=='5561'] 100 loops, best of 3: 11.9 ms per loop 

o

 %timeit df_user1_noloc = df[df.user_id=='5561'] 100 loops, best of 3: 12 ms per loop 

Entonces, ¿por qué usar loc?

Editar: Esto ha sido marcado como una pregunta duplicada. Pero a pesar de la explicación de pandas iloc vs ix vs loc? menciona que *

puede hacer la recuperación de columnas con solo usar el dataframe getitem :

*

 df['time'] # equivalent to df.loc[:, 'time'] 

no dice por qué usamos loc, aunque sí explica muchas características de loc, mi pregunta específica es ‘¿por qué no omitir loc’? Por lo que he aceptado una respuesta muy detallada a continuación.

Además, en la otra discusión, la respuesta (que no creo que sea una respuesta) está muy oculta en la discusión y cualquier persona que busque lo que estaba buscando encontraría difícil encontrar la información y estaría mucho mejor atendida por la respuesta proporcionada a mi pregunta

  • Explícito es mejor que implícito.

    df[boolean_mask] selecciona filas donde boolean_mask es True, pero hay un caso de esquina en el que es posible que no quieras: cuando df tiene tags de columna con valores booleanos:

     In [229]: df = pd.DataFrame({True:[1,2,3],False:[3,4,5]}); df Out[229]: False True 0 3 1 1 4 2 2 5 3 

    Es posible que desee utilizar df[[True]] para seleccionar la columna True . En su lugar, plantea un ValueError :

     In [230]: df[[True]] ValueError: Item wrong length 1 instead of 3. 

    Versus usando loc :

     In [231]: df.loc[[True]] Out[231]: False True 0 3 1 

    En contraste, lo siguiente no eleva ValueError a pesar de que la estructura de df2 es casi la misma que df1 anterior:

     In [258]: df2 = pd.DataFrame({'A':[1,2,3],'B':[3,4,5]}); df2 Out[258]: AB 0 1 3 1 2 4 2 3 5 In [259]: df2[['B']] Out[259]: B 0 3 1 4 2 5 

    Por lo tanto, df[boolean_mask] no siempre se comporta igual que df.loc[boolean_mask] . Aunque este es posiblemente un caso de uso improbable, recomendaría usar siempre df.loc[boolean_mask] lugar de df[boolean_mask] porque el significado de la syntax de df.loc es explícito. Con df.loc[indexer] usted sabe automáticamente que df.loc está seleccionando filas. Por el contrario, no está claro si df[indexer] seleccionará filas o columnas (o elevará ValueError ) sin conocer detalles sobre el indexer y df .

  • df.loc[row_indexer, column_index] puede seleccionar filas y columnas. df[indexer] solo puede seleccionar filas o columnas según el tipo de valores en el indexer y el tipo de valores de columna que tenga (nuevamente, ¿son booleanos?).

     In [237]: df2.loc[[True,False,True], 'B'] Out[237]: 0 3 2 5 Name: B, dtype: int64 
  • Cuando se pasa una df.loc a df.loc los puntos finales se incluyen en el rango. Cuando se pasa una df[...] a df[...] división se interpreta como un intervalo medio abierto:

     In [239]: df2.loc[1:2] Out[239]: AB 1 2 4 2 3 5 In [271]: df2[1:2] Out[271]: AB 1 2 4