En Pandas, cuando selecciono una etiqueta que solo tiene una entrada en el índice, obtengo una Serie, pero cuando selecciono una entrada que tiene más de una entrada, obtengo un marco de datos.
¿Porqué es eso? ¿Hay alguna forma de asegurar que siempre recupere un marco de datos?
In [1]: import pandas as pd
In [2]: df = pd.DataFrame(data=range(5), index=[1, 2, 3, 3, 3])
In [3]: type(df.loc[3])
Out[3]: pandas.core.frame.DataFrame
In [4]: type(df.loc[1])
Out[4]: pandas.core.series.Series
KeyError
cuando lo intento.loc[[nonexistent_label]]
..loc
es mucho más lento que sin ella. Para seguir siendo legible pero también mucho más rápido, mejor usodf.loc[1:1]
Tiene un índice con tres elementos de índice
3
. Por esta razóndf.loc[3]
, devolverá un marco de datos.La razón es que no especifica la columna. Entonces
df.loc[3]
selecciona tres elementos de todas las columnas (que es la columna0
), mientrasdf.loc[3,0]
que devolverá una Serie. Por ejemplo,df.loc[1:2]
también devuelve un marco de datos, porque corta las filas.Al seleccionar una sola fila (como
df.loc[1]
) se devuelve una serie con los nombres de las columnas como índice.Si desea asegurarse de tener siempre un DataFrame, puede dividir como
df.loc[1:1]
. Otra opción es la indexación booleana (df.loc[df.index==1]
) o el método take (df.take([0])
, ¡pero esta ubicación no usa etiquetas!).fuente
Úselo
df['columnName']
para obtener una serie ydf[['columnName']]
un marco de datos.fuente
El TLDR
Cuando usas
loc
df.loc[:]
= Marco de datosdf.loc[int]
= Marco de datos si tiene más de una columna y Serie si solo tiene 1 columna en el marco de datosdf.loc[:, ["col_name"]]
= Marco de datosdf.loc[:, "col_name"]
= SerieNo usando
loc
df["col_name"]
= Seriedf[["col_name"]]
= Marco de datosfuente
Escribiste en un comentario a la respuesta de joris:
Una sola fila no se convierte en una serie.
Es ES una Serie:
No, I don't think so, in fact; see the edit
El modelo de datos de los objetos Pandas se ha elegido así. La razón ciertamente radica en el hecho de que asegura algunas ventajas que no conozco (no entiendo completamente la última oración de la cita, tal vez sea la razón)
.
Editar: no estoy de acuerdo conmigo
Una trama de datos no puede estar compuesto de elementos que ser Series, porque el código siguiente da el mismo tipo "Series", así como para una fila como para una columna:
resultado
Entonces, no tiene sentido pretender que un DataFrame está compuesto por Series porque, ¿qué se supone que son estas Series: columnas o filas? Estúpida pregunta y visión.
.
Entonces, ¿qué es un DataFrame?
En la versión anterior de esta respuesta, hice esta pregunta, tratando de encontrar la respuesta a la
Why is that?
parte de la pregunta del OP y la interrogación similarsingle rows to get converted into a series - why not a data frame with one row?
en uno de sus comentarios,mientras que la
Is there a way to ensure I always get back a data frame?
parte ha sido respondida por Dan Allan.Luego, como los documentos de los Pandas citados anteriormente dicen que las estructuras de datos de los pandas se ven mejor como contenedores de datos de dimensiones inferiores, me pareció que la comprensión del por qué se encontraría en las características de la naturaleza de las estructuras de DataFrame.
Sin embargo, me di cuenta de que este consejo citado no debe tomarse como una descripción precisa de la naturaleza de las estructuras de datos de Pandas.
Este consejo no significa que un DataFrame sea un contenedor de Series.
Expresa que la representación mental de un DataFrame como un contenedor de Series (ya sea filas o columnas según la opción considerada en un momento de un razonamiento) es una buena forma de considerar DataFrames, incluso si no es estrictamente el caso en la realidad. "Bueno" significa que esta visión permite utilizar DataFrames con eficiencia. Eso es todo.
.
Entonces, ¿qué es un objeto DataFrame?
La clase DataFrame produce instancias que tienen una estructura particular originada en la clase base NDFrame , a su vez derivada de la clase base PandasContainer que también es una clase principal de la clase Series .
Tenga en cuenta que esto es correcto para Pandas hasta la versión 0.12. En la próxima versión 0.13, Series se derivará también solo de la clase NDFrame .
resultado
Entonces, tengo entendido ahora que una instancia de DataFrame tiene ciertos métodos que se han diseñado para controlar la forma en que se extraen los datos de las filas y columnas.
Las formas en que funcionan estos métodos de extracción se describen en esta página: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing
Encontramos en él el método dado por Dan Allan y otros métodos.
¿Por qué estos métodos de extracción se han elaborado como estaban?
Eso es ciertamente porque han sido evaluados como los que ofrecen mejores posibilidades y facilidad en el análisis de datos.
Es precisamente lo que se expresa en esta frase:
El por qué de la extracción de datos de una instancia de DataFRame no radica en su estructura, sino en el por qué de esta estructura. Supongo que la estructura y el funcionamiento de la estructura de datos de los Pandas han sido cincelados para que sean lo más intelectualmente intuitivos posible, y que para comprender los detalles hay que leer el blog de Wes McKinney.
fuente
Si el objetivo es obtener un subconjunto del conjunto de datos usando el índice, es mejor evitar usar
loc
oiloc
. En su lugar, debe usar una sintaxis similar a esta:fuente
Si también selecciona en el índice del marco de datos, el resultado puede ser un marco de datos o una serie o puede ser una serie o un escalar (valor único).
Esta función asegura que siempre obtenga una lista de su selección (si el df, el índice y la columna son válidos):
fuente