Convierta el marco de datos de pandas en series


98

Soy algo nuevo en pandas. Tengo un marco de datos de pandas de 1 fila por 23 columnas.

¿Quiero convertir esto en una serie? Me pregunto cuál es la forma más pitónica de hacer esto.

Lo he intentado pd.Series(myResults)pero se queja ValueError: cannot copy sequence with size 23 to array axis with dimension 1. No es lo suficientemente inteligente como para darse cuenta de que sigue siendo un "vector" en términos matemáticos.

¡Gracias!

Respuestas:


64

No es lo suficientemente inteligente como para darse cuenta de que sigue siendo un "vector" en términos matemáticos.

Diga más bien que es lo suficientemente inteligente como para reconocer una diferencia en dimensionalidad. :-)

Creo que lo más simple que puede hacer es seleccionar esa fila posicionalmente usando iloc, lo que le da una Serie con las columnas como el nuevo índice y los valores como los valores:

>>> df = pd.DataFrame([list(range(5))], columns=["a{}".format(i) for i in range(5)])
>>> df
   a0  a1  a2  a3  a4
0   0   1   2   3   4
>>> df.iloc[0]
a0    0
a1    1
a2    2
a3    3
a4    4
Name: 0, dtype: int64
>>> type(_)
<class 'pandas.core.series.Series'>

2
O, de otra manera:df.T
ako

14
@ako: sin df.Tembargo, no produce una serie, solo un DataFrame transpuesto.
DSM

@DSM. Eso es cierto, df.T.iloc [0]
Antonio Andrés

El único problema con el uso df.iloces que si tiene un df vacío, esto generará un IndexError. Para evitar eso, después de transponer su df, use el df.squeezemétodo. Árbitro. a pandas.pydata.org/pandas-docs/stable/reference/api/…
Nicolas Fonteyne

60

Puede transponer el marco de datos de una sola fila (que aún da como resultado un marco de datos) y luego comprimir los resultados en una serie (el inverso de to_frame).

df = pd.DataFrame([list(range(5))], columns=["a{}".format(i) for i in range(5)])

>>> df.T.squeeze()  # Or more simply, df.squeeze() for a single row dataframe.
a0    0
a1    1
a2    2
a3    3
a4    4
Name: 0, dtype: int64

Nota: Para acomodar el punto planteado por @IanS (aunque no está en la pregunta del OP), pruebe el tamaño del marco de datos. Supongo que dfes un marco de datos, pero los casos extremos son un marco de datos vacío, un marco de datos de forma (1, 1) y un marco de datos con más de una fila, en cuyo caso el uso debe implementar la funcionalidad deseada.

if df.empty:
    # Empty dataframe, so convert to empty Series.
    result = pd.Series()
elif df.shape == (1, 1)
    # DataFrame with one value, so convert to series with appropriate index.
    result = pd.Series(df.iat[0, 0], index=df.columns)
elif len(df) == 1:
    # Convert to series per OP's question.
    result = df.T.squeeze()
else:
    # Dataframe with multiple rows.  Implement desired behavior.
    pass

Esto también se puede simplificar según la respuesta proporcionada por @themachinist.

if len(df) > 1:
    # Dataframe with multiple rows.  Implement desired behavior.
    pass
else:
    result = pd.Series() if df.empty else df.iloc[0, :]

11
Tenga en cuenta que me encontré con un pequeño problema al usar squeeze. Para un marco de datos de forma (1, 1), devolverá, no una serie de longitud 1, sino un escalar numpy. Esto llevó a un error difícil de detectar cuando se usa squeezeen objetos de longitud desconocida (por ejemplo, con groupby).
IanS

2
"¡Gracias! Df.squeeze () funcionó cuando df.iloc [:, 0] y df.ix [:, 0] produjeron demasiados errores de índices"
Afflatus

3
¿Y por qué es la inversa de to_frameno to_serieso pd.Series(df)...?
jhin

4
No necesitas.T
elgehelge

1
@IanS pasa el argumento df.squeeze(axis=0)o df.squeeze(axis=1)(dependiendo del eje que quieras conservar) para evitar eso
Nicolas Fonteyne


4

De otra manera -

Suponga que myResult es el dataFrame que contiene sus datos en forma de 1 col y 23 filas

// label your columns by passing a list of names
myResult.columns = ['firstCol']

// fetch the column in this way, which will return you a series
myResult = myResult['firstCol']

print(type(myResult))

De manera similar, puede obtener series de Dataframe con múltiples columnas.


3

También puede usar stack ()

df= DataFrame([list(range(5))], columns = [“a{}”.format(I) for I in range(5)])

Después de ejecutar df, ejecute:

df.stack()

Obtienes tu marco de datos en serie


0
data = pd.DataFrame({"a":[1,2,3,34],"b":[5,6,7,8]})
new_data = pd.melt(data)
new_data.set_index("variable", inplace=True)

Esto da un marco de datos con índice como nombre de columna de datos y todos los datos están presentes en la columna "valores"


5
¡Bienvenido a Stack Overflow! ¿Cómo responde esto a la pregunta? Su código no devuelve una serie como pide la pregunta
Gricey
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.