139 votes

Quelle est la différence entre l'utilisation de loc et l'utilisation de simples crochets pour filtrer des colonnes dans Pandas/Python ?

J'ai remarqué trois méthodes pour sélectionner une colonne dans un DataFrame Pandas :

Première méthode de sélection d'une colonne à l'aide de loc :

df_new = df.loc[:, 'col1']

Deuxième méthode - semble plus simple et plus rapide :

df_new = df['col1']

Troisième méthode - la plus pratique :

df_new = df.col1

Y a-t-il une différence entre ces trois méthodes ? Je ne le pense pas, dans ce cas je préfère utiliser la troisième méthode.

Je suis surtout curieux de savoir pourquoi il semble y avoir trois méthodes pour faire la même chose.

1 votes

Ou alors df.col1 ? Ces trois méthodes sont essentiellement équivalentes pour le cas très simple de la sélection d'une colonne. .loc vous permettra de faire bien plus que de sélectionner une colonne. Duplicata possible de stackoverflow.com/questions/31593201/

1 votes

Ils font la même chose pour les tranches simples. loc est plus explicite, surtout lorsque vos colonnes sont des nombres.

0 votes

Merci @juanpa.arrivillaga. Bon point concernant df.col1, qui est encore une autre méthode de sélection des colonnes. En fait, j'ai déjà examiné cette autre question, plusieurs fois. C'est très bien pour expliquer loc et iloc. Cependant, cette question concerne l'autre méthode : "df['col1']". Je ne comprends pas pourquoi il existe deux (ou trois) façons équivalentes de faire ce qui semble être la même chose.

140voto

ayhan Points 33889

Dans les situations suivantes, ils se comportent de la même manière :

  1. Sélection d'une seule colonne ( df['A'] est la même chose que df.loc[:, 'A'] -> sélectionne la colonne A)
  2. Sélection d'une liste de colonnes ( df[['A', 'B', 'C']] est la même chose que df.loc[:, ['A', 'B', 'C']] -> sélectionne les colonnes A, B et C)
  3. Découpage par rangées ( df[1:3] est la même chose que df.iloc[1:3] -> sélectionne les lignes 1 et 2. Notez cependant que si vous découpez les lignes avec loc au lieu de iloc vous obtiendrez les rangées 1, 2 et 3 en supposant que vous avez une RangeIndex . Voir les détails aquí .)

Cependant, [] ne fonctionne pas dans les situations suivantes :

  1. Vous pouvez sélectionner une seule ligne avec df.loc[row_label]
  2. Vous pouvez sélectionner une liste de lignes avec df.loc[[row_label1, row_label2]]
  3. Vous pouvez découper les colonnes avec df.loc[:, 'A':'C']

Ces trois éléments ne peuvent être réalisés avec [] . Plus important encore, si votre sélection implique à la fois des lignes et des colonnes, l'affectation devient problématique.

df[1:3]['A'] = 5

Cette opération sélectionne les lignes 1 et 2, puis la colonne 'A' de l'objet retourné et lui attribue la valeur 5. Le problème est que l'objet de retour peut être une copie et que cela peut ne pas modifier le DataFrame réel. Cela soulève SettingWithCopyWarning . La manière correcte de faire ce devoir est :

df.loc[1:3, 'A'] = 5

Avec .loc vous êtes assuré de modifier le DataFrame original. Il vous permet également de découper des colonnes ( df.loc[:, 'C':'F'] ), sélectionner une seule ligne ( df.loc[5] ), et sélectionner une liste de lignes ( df.loc[[1, 2, 5]] ).

Notez également que ces deux éléments n'ont pas été inclus dans l'API en même temps. .loc a été ajouté beaucoup plus tard comme un indexeur plus puissant et plus explicite. Voir La réponse de unutbu pour plus de détails.


Note : Obtenir des colonnes avec [] vs . est un sujet complètement différent. . n'est là que par commodité. Elle ne permet d'accéder qu'aux colonnes dont les noms sont des identifiants Python valides (c'est-à-dire qu'ils ne peuvent pas contenir d'espaces, ils ne peuvent pas être composés de chiffres...). Elle ne peut pas être utilisée lorsque les noms entrent en conflit avec les méthodes Series/DataFrame. Elle ne peut pas non plus être utilisée pour des colonnes inexistantes (c'est-à-dire que l'affectation df.a = 1 ne fonctionnera pas s'il n'y a pas de colonne a ). En dehors de cela, . y [] sont les mêmes.

2 votes

Que voulez-vous dire par "l'objet retourné peut être une copie" ? C'est un peu confus. Dois-je m'attendre à ce que la valeur renvoyée par df[1:3]['A'] = 5 pour être une copie ou non ?

2 votes

@AlessioF C'est le problème. Nous ne le savons pas vraiment. pandas ne donne aucune garantie sur ce que les retours de df.__getitem__(...) et sous le capot, la disposition de la mémoire du tableau stocké peut donner lieu à une vue ou à une copie. En général, lorsque vous travaillez sur un cadre de données avec un seul type de données, vous obtenez une vue, mais ce n'est pas garanti. Je crois qu'ils travaillent sur une nouvelle approche au lieu d'utiliser BlockManager qui est la principale source de ces problèmes.

8voto

Freeman Points 1725

loc est particulièrement utile lorsque l'indice n'est pas numérique (par exemple un DatetimeIndex) car vous pouvez obtenir rangées avec des étiquettes particulières de l'index :

df.loc['2010-05-04 07:00:00']
df.loc['2010-1-1 0:00:00':'2010-12-31 23:59:59 ','Price']

Cependant [] est destiné à obtenir colonnes avec des noms particuliers :

df['Price']

Avec [] vous pouvez également filtrer rangées mais elle est plus élaborée :

df[df['Date'] < datetime.datetime(2010,1,1,7,0,0)]['Price']

1voto

Pedram Parsian Points 3195

Si vous ne savez pas laquelle de ces approches est (au moins) la plus recommandée pour votre cas d'utilisation, jetez un coup d'œil à ces brèves instructions de la part de la Commission européenne. tutoriel pandas :

  • Quand sélection de sous-ensembles de données entre crochets [] sont utilisés.

  • À l'intérieur de ces parenthèses, vous pouvez utiliser une étiquette de colonne/rangée unique, une liste liste d'étiquettes de colonnes/de lignes, une tranche d'étiquettes, une expression conditionnelle ou un deux-points.

  • Sélectionnez des lignes et/ou des colonnes spécifiques en utilisant loc lors de l'utilisation de la ligne et noms de colonnes

  • Sélectionnez des lignes et/ou des colonnes spécifiques en utilisant iloc lorsque vous utilisez le positions dans le tableau

  • Vous pouvez attribuer de nouvelles valeurs à une sélection basée sur loc / iloc .

J'ai mis en évidence certains points pour rendre encore plus claires les différences entre les cas d'utilisation.

0voto

Matthew Son Points 73

Il semble y avoir une différence entre df.loc[] et df[] lorsque vous créez un cadre de données avec plusieurs colonnes.

Vous pouvez vous référer à cette question : Existe-t-il un moyen agréable de générer des colonnes multiples à l'aide de .loc ?

Ici, vous ne pouvez pas générer plusieurs colonnes en utilisant df.loc[:,['name1','name2']] mais vous pouvez le faire en utilisant simplement les doubles crochets df[['name1','name2']] . (Je me demande pourquoi ils se comportent différemment).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X