Dans Pandas, lorsque je sélectionne une étiquette qui n'a qu'une seule entrée dans l'index, je récupère une série, mais lorsque je sélectionne une entrée qui a plus d'une entrée, je récupère une trame de données.
Pourquoi donc? Existe-t-il un moyen de m'assurer de toujours récupérer une trame de données?
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
quand j'essaye.loc[[nonexistent_label]]
..loc
est beaucoup plus lente que sans elle. Pour être toujours lisible mais aussi beaucoup plus rapide, mieux utiliserdf.loc[1:1]
Vous avez un index avec trois éléments d'index
3
. Pour cette raisondf.loc[3]
retournera un dataframe.La raison est que vous ne spécifiez pas la colonne.
df.loc[3]
Sélectionne donc trois éléments de toutes les colonnes (qui est colonne0
), tandis quedf.loc[3,0]
retournera une série. Par exemple,df.loc[1:2]
renvoie également un dataframe, car vous découpez les lignes.La sélection d'une seule ligne (as
df.loc[1]
) renvoie une série avec les noms de colonne comme index.Si vous voulez être sûr d'avoir toujours un DataFrame, vous pouvez découper comme
df.loc[1:1]
. Une autre option est l'indexation booléenne (df.loc[df.index==1]
) ou la méthode take (df.take([0])
, mais cet emplacement utilisé n'est pas des étiquettes!).la source
Le TLDR
Lors de l'utilisation
loc
df.loc[:]
= Dataframedf.loc[int]
= Dataframe si vous avez plus d'une colonne et Series si vous n'avez qu'une seule colonne dans le dataframedf.loc[:, ["col_name"]]
= Dataframedf.loc[:, "col_name"]
= SérieN'utilise pas
loc
df["col_name"]
= Sériedf[["col_name"]]
= Dataframela source
Utilisez
df['columnName']
pour obtenir une série etdf[['columnName']]
pour obtenir un Dataframe.la source
Vous avez écrit dans un commentaire à la réponse de Joris:
Une seule ligne n'est pas convertie en série.
Il EST une série:
No, I don't think so, in fact; see the edit
Le modèle de données des objets Pandas a été choisi comme ça. La raison réside certainement dans le fait que cela garantit des avantages que je ne connais pas (je ne comprends pas complètement la dernière phrase de la citation, peut-être que c'est la raison)
.
Edit: je ne suis pas d'accord avec moi
Une trame de données ne peut pas être composé d'éléments qui être série, car le code suivant donne le même type « série » et pour une ligne que pour une colonne:
résultat
Donc, il n'y a aucun sens à prétendre qu'un DataFrame est composé de Series parce que ce que cesdites Series seraient supposées être: des colonnes ou des lignes? Question et vision stupides.
.
Alors qu'est-ce qu'un DataFrame?
Dans la version précédente de cette réponse, j'ai posé cette question, en essayant de trouver la réponse à la
Why is that?
partie de la question du PO et à l'interrogatoire similairesingle rows to get converted into a series - why not a data frame with one row?
dans l'un de ses commentaires,alors que la
Is there a way to ensure I always get back a data frame?
partie a été répondue par Dan Allan.Ensuite, comme les documents des Pandas cités ci-dessus indiquent que les structures de données des pandas sont mieux vues comme des conteneurs de données de dimension inférieure, il m'a semblé que la compréhension du pourquoi se trouverait dans les caractéristiques de la nature des structures DataFrame.
Cependant, j'ai réalisé que cet avis cité ne doit pas être considéré comme une description précise de la nature des structures de données de Pandas.
Ce conseil ne signifie pas qu'un DataFrame est un conteneur de Series.
Il exprime que la représentation mentale d'un DataFrame comme conteneur de Series (soit des lignes, soit des colonnes selon l'option considérée à un moment d'un raisonnement) est un bon moyen de considérer les DataFrames, même si ce n'est pas strictement le cas dans la réalité. «Bon» signifie que cette vision permet d'utiliser les DataFrames avec efficacité. C'est tout.
.
Alors qu'est-ce qu'un objet DataFrame?
La classe DataFrame produit des instances qui ont une structure particulière issue de la classe de base NDFrame , elle-même dérivée de la classe de base PandasContainer qui est également une classe parente de la classe Series .
Notez que cela est correct pour Pandas jusqu'à la version 0.12. Dans la prochaine version 0.13, Series dérivera également de la classe NDFrame uniquement.
résultat
Donc, je crois comprendre maintenant qu'une instance de DataFrame a certaines méthodes qui ont été conçues afin de contrôler la façon dont les données sont extraites des lignes et des colonnes.
Le fonctionnement de ces méthodes d'extraction est décrit dans cette page: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing
On y retrouve la méthode donnée par Dan Allan et d'autres méthodes.
Pourquoi ces méthodes d'extraction ont-elles été élaborées telles quelles?
C'est certainement parce qu'ils ont été évalués comme ceux offrant les meilleures possibilités et la facilité d'analyse des données.
C'est précisément ce qui est exprimé dans cette phrase:
Le pourquoi de l'extraction des données d'une instance DataFRame ne réside pas dans sa structure, il réside dans le pourquoi de cette structure. Je suppose que la structure et le fonctionnement de la structure de données des Pandas ont été ciselés afin d'être le plus intellectuellement intuitif possible, et que pour comprendre les détails, il faut lire le blog de Wes McKinney.
la source
Si l'objectif est d'obtenir un sous-ensemble de l'ensemble de données à l'aide de l'index, il est préférable d'éviter d'utiliser
loc
ouiloc
. Au lieu de cela, vous devez utiliser une syntaxe similaire à celle-ci:la source
Si vous sélectionnez également sur l'index de la trame de données, le résultat peut être une trame de données ou d' une série ou il peut être une série ou un scalaire (valeur unique).
Cette fonction garantit que vous obtenez toujours une liste de votre sélection (si le df, l'index et la colonne sont valides):
la source