Quelqu'un peut-il expliquer en quoi ces trois méthodes de découpage sont différentes?
J'ai vu les documents et j'ai vu ces réponses , mais je n'arrive toujours pas à expliquer en quoi les trois sont différents. Pour moi, ils semblent interchangeables en grande partie, car ils sont aux niveaux inférieurs de tranchage.
Par exemple, disons que nous voulons obtenir les cinq premières lignes de a DataFrame
. Comment se fait-il que ces trois éléments fonctionnent?
df.loc[:5]
df.ix[:5]
df.iloc[:5]
Quelqu'un peut-il présenter trois cas où la distinction des usages est plus claire?
Réponses:
Remarque: dans les versions 0.20.0 et supérieures de pandas,
ix
est déconseillé et l'utilisation deloc
etiloc
est plutôt encouragée. J'ai laissé les parties de cette réponse qui décriventix
intactes comme référence pour les utilisateurs des versions antérieures de pandas. Des exemples ont été ajoutés ci-dessous montrant des alternatives àix
.Tout d'abord, voici un récapitulatif des trois méthodes:
loc
obtient des lignes (ou colonnes) avec des étiquettes particulières de l'index.iloc
obtient des lignes (ou colonnes) à des positions particulières dans l'index (donc il ne prend que des entiers).ix
essaie généralement de se comporter commeloc
mais revient à se comporter commeiloc
si une étiquette n'est pas présente dans l'index.Il est important de noter certaines subtilités qui peuvent être
ix
légèrement délicates à utiliser:si l'index est de type entier,
ix
n'utilisera que l'indexation basée sur les étiquettes et ne retombera pas sur l'indexation basée sur la position. Si l'étiquette n'est pas dans l'index, une erreur est générée.si l'index ne contient pas uniquement des entiers, alors étant donné un entier,
ix
utilisera immédiatement l'indexation basée sur la position plutôt que l'indexation basée sur l'étiquette. Si toutefoisix
on lui donne un autre type (par exemple une chaîne), il peut utiliser une indexation basée sur les étiquettes.Pour illustrer les différences entre les trois méthodes, considérons la série suivante:
Nous allons voir le découpage avec la valeur entière
3
.Dans ce cas,
s.iloc[:3]
nous renvoie les 3 premières lignes (car il traite 3 comme une position) ets.loc[:3]
nous renvoie les 8 premières lignes (car il traite 3 comme une étiquette):Remarque
s.ix[:3]
renvoie la même séries.loc[:3]
car il recherche d'abord l'étiquette plutôt que de travailler sur la position (et l'index pours
est de type entier).Et si nous essayons avec une étiquette entière qui n'est pas dans l'index (disons
6
)?Renvoie ici
s.iloc[:6]
les 6 premières lignes de la série comme prévu. Cependant,s.loc[:6]
déclenche une erreur KeyError puisqu'elle6
n'est pas dans l'index.Selon les subtilités notées ci-dessus,
s.ix[:6]
déclenche maintenant une erreur KeyError car il essaie de fonctionner commeloc
mais ne peut pas trouver un6
dans l'index. Parce que notre index est de type entierix
ne revient pas à se comporter commeiloc
.Si, cependant, notre index était de type mixte, étant donné qu'un entier
ix
se comporterait commeiloc
immédiatement au lieu de déclencher une erreur de clé:Gardez à l'esprit que vous
ix
pouvez toujours accepter des non-entiers et vous comporter commeloc
:Comme conseil général, si vous indexez uniquement à l'aide d'étiquettes, ou uniquement à l'aide de positions entières, respectez
loc
ouiloc
pour éviter des résultats inattendus - essayez de ne pas utiliserix
.Combinaison d'une indexation basée sur la position et basée sur une étiquette
Parfois, étant donné un DataFrame, vous souhaiterez mélanger les méthodes d'indexation d'étiquette et de position pour les lignes et les colonnes.
Par exemple, considérez le DataFrame suivant. Comment découper au mieux les lignes jusqu'au «c» inclus et prendre les quatre premières colonnes?
Dans les versions antérieures de pandas (avant 0.20.0), cela
ix
vous permet de le faire assez bien - nous pouvons découper les lignes par étiquette et les colonnes par position (notez que pour les colonnes,ix
par défaut, le découpage basé sur la position4
n'est pas un nom de colonne ):Dans les versions ultérieures de pandas, nous pouvons obtenir ce résultat à l'aide
iloc
et à l'aide d'une autre méthode:get_loc()
est une méthode d'index qui signifie "obtenir la position de l'étiquette dans cet index". Notez que puisque le découpage aveciloc
est exclusif de son point de terminaison, nous devons ajouter 1 à cette valeur si nous voulons également la ligne 'c'.Il y a d'autres exemples dans la documentation des pandas ici .
la source
loc
,iloc
etix
pourrait encore déclencher l'avertissement si elles sont enchaînées. L'utilisation de l'exemple DataFrame dans les documents liésdfmi.loc[:, 'one'].loc[:, 'second']
déclenche l'avertissement, tout commedfmi['one']['second']
une copie des données (plutôt qu'une vue) peut être renvoyée par la première opération d'indexation.df.ix[date, 'Cash']
?loc
ouix
devraient fonctionner dans ce cas. Par exemple,df.loc['2016-04-29', 'Cash']
retournera tous les index de ligne avec cette date particulière de la colonne 'Cash'. (Vous pouvez être aussi précis que vous le souhaitez lors de la récupération des index avec des chaînes, par exemple'2016-01'
, sélectionnera tous les horaires tombant en janvier 2016, `` 2016-01-02 11 '' sélectionnera les horaires le 2 janvier 2016 avec l'heure 11: ??: ?? .)iloc
fonctionne basé sur le positionnement entier. Donc, peu importe vos étiquettes de ligne, vous pouvez toujours, par exemple, obtenir la première ligne en faisantou les cinq dernières lignes en faisant
Vous pouvez également l'utiliser sur les colonnes. Cela récupère la 3ème colonne:
Vous pouvez les combiner pour obtenir des intersections de lignes et de colonnes:
D'un autre côté,
.loc
utilisez des indices nommés. Configurons un bloc de données avec des chaînes comme étiquettes de ligne et de colonne:Ensuite, nous pouvons obtenir la première ligne en
et les deux deuxièmes rangées de la
'date'
colonne paretc. Maintenant, il convient probablement de souligner que les indices de ligne et de colonne par défaut pour a
DataFrame
sont des entiers de 0 et dans ce casiloc
,loc
ils fonctionneraient de la même manière. C'est pourquoi vos trois exemples sont équivalents. Si vous aviez un index non numérique tel que des chaînes ou des heures,df.loc[:5]
cela déclencherait une erreur.En outre, vous pouvez effectuer une récupération de colonne en utilisant simplement le bloc de données
__getitem__
:Supposons maintenant que vous vouliez mélanger la position et l'indexation nommée, c'est-à-dire l'indexation en utilisant des noms sur les lignes et des positions sur les colonnes (pour clarifier, je veux dire sélectionner dans notre bloc de données, plutôt que de créer un bloc de données avec des chaînes dans l'index des lignes et des entiers dans l'index de la colonne). C'est là
.ix
qu'intervient:Je pense qu'il convient également de mentionner que vous pouvez également transmettre des vecteurs booléens à la
loc
méthode. Par exemple:Renvoie les 1er et 3e rangées de
df
. C'est équivalent àdf[b]
pour la sélection, mais il peut également être utilisé pour l'affectation via des vecteurs booléens:la source
df.loc[:, :]
. Il peut être utilisé pour réaffecter les valeurs de l'ensembleDataFrame
ou en créer une vue.À mon avis, la réponse acceptée prête à confusion, car elle utilise un DataFrame avec uniquement des valeurs manquantes. Je n'aime pas non plus le terme basé sur la position
.iloc
et préfère plutôt l' emplacement entier car il est beaucoup plus descriptif et exactement ce qui.iloc
signifie. Le mot clé est INTEGER - a.iloc
besoin d'INTÉGRATEURS.Voir ma série de blogs extrêmement détaillée sur la sélection de sous-ensembles pour en savoir plus
.ix est obsolète et ambigu et ne doit jamais être utilisé
Parce qu'il
.ix
est obsolète, nous nous concentrerons uniquement sur les différences entre.loc
et.iloc
.Avant de parler des différences, il est important de comprendre que les DataFrames ont des étiquettes qui aident à identifier chaque colonne et chaque index. Jetons un coup d'œil à un exemple de DataFrame:
Tous les mots en gras sont les étiquettes. Les étiquettes,
age
,color
,food
,height
,score
etstate
sont utilisés pour les colonnes . Les autres étiquettes,Jane
,Nick
,Aaron
,Penelope
,Dean
,Christina
,Cornelia
sont utilisés pour l' indice .Les principaux moyens de sélectionner des lignes particulières dans un DataFrame sont avec les indexeurs
.loc
et.iloc
. Chacun de ces indexeurs peut également être utilisé pour sélectionner simultanément des colonnes, mais il est plus facile de se concentrer uniquement sur les lignes pour l'instant. De plus, chacun des indexeurs utilise un ensemble de crochets qui suivent immédiatement leur nom pour effectuer leurs sélections..loc sélectionne les données uniquement par des étiquettes
Nous parlerons d'abord de l'
.loc
indexeur qui sélectionne uniquement les données par les étiquettes d'index ou de colonne. Dans notre exemple DataFrame, nous avons fourni des noms significatifs comme valeurs pour l'index. De nombreux DataFrames n'auront pas de noms significatifs et seront, par défaut, uniquement des entiers de 0 à n-1, où n est la longueur du DataFrame.Vous pouvez utiliser trois entrées différentes pour
.loc
Sélection d'une seule ligne avec .loc avec une chaîne
Pour sélectionner une seule ligne de données, placez l'étiquette d'index à l'intérieur des crochets suivants
.loc
.Cela renvoie la ligne de données sous forme de série
Sélection de plusieurs lignes avec .loc avec une liste de chaînes
Cela renvoie un DataFrame avec les lignes dans l'ordre spécifié dans la liste:
Sélection de plusieurs lignes avec .loc avec notation par tranche
La notation de tranche est définie par des valeurs de début, d'arrêt et de pas. Lors du découpage par étiquette, pandas inclut la valeur d'arrêt dans le retour. Les tranches suivantes d'Aaron à Dean, inclusivement. Sa taille de pas n'est pas explicitement définie mais définie par défaut sur 1.
Les tranches complexes peuvent être prises de la même manière que les listes Python.
.iloc sélectionne les données uniquement par emplacement entier
Passons maintenant à
.iloc
. Chaque ligne et colonne de données dans un DataFrame a un emplacement entier qui le définit. Ceci s'ajoute au libellé affiché visuellement dans la sortie . L'emplacement entier est simplement le nombre de lignes / colonnes à partir du haut / gauche commençant à 0.Vous pouvez utiliser trois entrées différentes pour
.iloc
Sélection d'une seule ligne avec .iloc avec un entier
Cela renvoie la 5ème ligne (emplacement entier 4) en tant que série
Sélection de plusieurs lignes avec .iloc avec une liste d'entiers
Cela renvoie un DataFrame des troisième et avant-dernière lignes:
Sélection de plusieurs lignes avec .iloc avec notation par tranche
Sélection simultanée de lignes et de colonnes avec .loc et .iloc
Une excellente capacité des deux
.loc/.iloc
est leur capacité à sélectionner simultanément les lignes et les colonnes. Dans les exemples ci-dessus, toutes les colonnes ont été renvoyées à partir de chaque sélection. Nous pouvons choisir des colonnes avec les mêmes types d'entrées que pour les lignes. Nous devons simplement séparer la sélection des lignes et des colonnes par une virgule .Par exemple, nous pouvons sélectionner les lignes Jane et Dean avec juste la hauteur, le score et l'état des colonnes comme ceci:
Cela utilise une liste d'étiquettes pour les lignes et une notation de tranche pour les colonnes
Nous pouvons naturellement effectuer des opérations similaires en
.iloc
utilisant uniquement des entiers.Sélection simultanée avec étiquettes et emplacement entier
.ix
a été utilisé pour effectuer des sélections simultanément avec des étiquettes et un emplacement entier, ce qui était utile mais parfois déroutant et ambigu et heureusement, il a été déconseillé. Dans le cas où vous devez effectuer une sélection avec un mélange d'étiquettes et d'emplacements entiers, vous devrez effectuer à la fois vos étiquettes de sélections ou des emplacements entiers.Par exemple, si nous voulons sélectionner des lignes
Nick
etCornelia
avec les colonnes 2 et 4, nous pourrions utiliser.loc
en convertissant les entiers en étiquettes avec ce qui suit:Ou bien, convertissez les étiquettes d'index en entiers avec la
get_loc
méthode d'index.Sélection booléenne
L'indexeur .loc peut également effectuer une sélection booléenne. Par exemple, si nous voulons trouver toutes les lignes dont l'âge est supérieur à 30 ans et renvoyer uniquement les colonnes
food
et,score
nous pouvons procéder comme suit:Vous pouvez répliquer cela avec
.iloc
mais vous ne pouvez pas lui passer une série booléenne. Vous devez convertir la série booléenne en un tableau numpy comme celui-ci:Sélection de toutes les lignes
Il est possible d'utiliser
.loc/.iloc
uniquement pour la sélection de colonnes. Vous pouvez sélectionner toutes les lignes en utilisant deux points comme ceci:L'opérateur d'indexation,,
[]
peut également sélectionner des lignes et des colonnes, mais pas simultanément.La plupart des gens connaissent le but principal de l'opérateur d'indexation DataFrame, qui est de sélectionner des colonnes. Une chaîne sélectionne une seule colonne en tant que série et une liste de chaînes sélectionne plusieurs colonnes en tant que DataFrame.
L'utilisation d'une liste sélectionne plusieurs colonnes
Ce que les gens connaissent moins, c'est que, lorsque la notation par tranche est utilisée, la sélection se fait par étiquettes de ligne ou par emplacement entier. C'est très déroutant et quelque chose que je n'utilise presque jamais, mais cela fonctionne.
L'explication de la
.loc/.iloc
sélection de lignes est hautement préférée. L'opérateur d'indexation seul ne peut pas sélectionner simultanément des lignes et des colonnes.la source