Convertir la trame de données pandas en série

98

Je suis un peu nouveau pour les pandas. J'ai une trame de données pandas de 1 ligne par 23 colonnes.

Je veux convertir cela en une série? Je me demande quelle est la façon la plus pythonique de faire cela?

J'ai essayé pd.Series(myResults)mais ça se plaint ValueError: cannot copy sequence with size 23 to array axis with dimension 1. Ce n'est pas assez intelligent pour réaliser que c'est toujours un «vecteur» en termes mathématiques.

Merci!

user1357015
la source

Réponses:

64

Ce n'est pas assez intelligent pour réaliser que c'est toujours un «vecteur» en termes mathématiques.

Dites plutôt que c'est assez intelligent pour reconnaître une différence de dimensionnalité. :-)

Je pense que la chose la plus simple que vous puissiez faire est de sélectionner cette ligne en utilisant la position iloc, ce qui vous donne une série avec les colonnes comme nouvel index et les valeurs comme valeurs:

>>> 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'>
DSM
la source
2
Ou, d'une autre manière:df.T
ako
14
@ako: df.Tne produit pas de Series, cependant, juste un DataFrame transposé.
DSM
@DSM. C'est vrai, df.T.iloc [0]
Antonio Andrés
Le seul problème avec l'utilisation df.ilocest que si vous avez un df vide, cela lèvera un fichier IndexError. Pour éviter cela, après avoir transposé votre df, utilisez la df.squeezeméthode. Réf. à pandas.pydata.org/pandas-docs/stable/reference/api/…
Nicolas Fonteyne
60

Vous pouvez transposer la trame de données à une ligne (qui aboutit toujours à une trame de données), puis presser les résultats dans une série (l'inverse 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

Remarque: pour prendre en compte le point soulevé par @IanS (même si ce n'est pas dans la question de l'OP), testez la taille du dataframe. Je suppose que dfc'est une trame de données, mais les cas extrêmes sont une trame de données vide, une trame de données de forme (1, 1) et une trame de données avec plus d'une ligne, auquel cas l'utilisation doit implémenter la fonctionnalité souhaitée.

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

Cela peut également être simplifié selon la réponse fournie par @themachinist.

if len(df) > 1:
    # Dataframe with multiple rows.  Implement desired behavior.
    pass
else:
    result = pd.Series() if df.empty else df.iloc[0, :]
Alexandre
la source
11
Notez que j'ai rencontré un petit problème en utilisant squeeze. Pour un dataframe de forme, (1, 1)il renverra, non pas une série de longueur 1, mais un scalaire numpy. Cela a conduit à un bug difficile à attraper lors de l'utilisation squeezesur des objets de longueur inconnue (par exemple avec groupby).
IanS
2
"Merci! Df.squeeze () a fonctionné lorsque df.iloc [:, 0] et df.ix [:, 0] ont tous deux produit trop d'erreur d'index"
Afflatus
3
Et pourquoi l'inverse de to_framenon to_seriesou pd.Series(df)...?
jhin
4
Vous n'avez pas besoin.T
elgehelge
1
@IanS passez l'argument df.squeeze(axis=0)ou df.squeeze(axis=1)(selon l'axe que vous voulez conserver) pour éviter ça
Nicolas Fonteyne
4

Autrement -

Supposons que myResult est le dataFrame qui contient vos données sous la forme de 1 col et 23 lignes

// 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 la même manière, vous pouvez obtenir des séries de Dataframe avec plusieurs colonnes.

Tauseef Malik
la source
3

Vous pouvez également utiliser stack ()

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

Après avoir exécuté df, puis exécutez:

df.stack()

Vous obtenez votre dataframe en série

Omo intelligent
la source
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)

Cela donne une trame de données avec un index comme nom de colonne de données et toutes les données sont présentes dans la colonne «valeurs»

user12230680
la source
5
Bienvenue dans Stack Overflow! Comment cela répond-il à la question? Votre code ne renvoie pas une série comme la question le demande
Gricey