Je suis tellement confus avec différentes méthodes d'indexation utilisées iloc
dans les pandas.
Disons que j'essaie de convertir un Dataframe 1-d en un Dataframe 2-d. J'ai d'abord le Dataframe 1-d suivant
a_array = [1,2,3,4,5,6,7,8]
a_df = pd.DataFrame(a_array).T
Et je vais convertir cela en un Dataframe 2D avec la taille de 2x4
. Je commence par prérégler le Dataframe 2D comme suit:
b_df = pd.DataFrame(columns=range(4),index=range(2))
Ensuite, j'utilise for-loop pour m'aider à convertir a_df
(1-d) en b_df
(2-d) avec le code suivant
for i in range(2):
b_df.iloc[i,:] = a_df.iloc[0,i*4:(i+1)*4]
Cela ne me donne que les résultats suivants
0 1 2 3
0 1 2 3 4
1 NaN NaN NaN NaN
Mais quand j'ai changé b_df.iloc[i,:]
pour b_df.iloc[i][:]
. Le résultat est correct comme le suivant, c'est ce que je veux
0 1 2 3
0 1 2 3 4
1 5 6 7 8
Quelqu'un pourrait-il m'expliquer quelle est la différence entre .iloc[i,:]
et .iloc[i][:]
est, et pourquoi a .iloc[i][:]
fonctionné dans mon exemple ci-dessus mais pas.iloc[i,:]
b_df.iloc[1] = a_df.iloc[0, 4:8]
affecte une série avec index[4, 5, 6, 7]
à une série avec index[0, 1, 2, 3]
. Il n'y a pas de chevauchement doncNaN
s est assigné à tous les éléments. Jusqu'à présent, cela a du sens pour moi. Mais comme vous, je ne sais pas pourquoib_df.iloc[1][:] = ...
se comporte différemment - inspecter les objetsb_df.iloc[1]
etb_df.iloc[1][:]
ne révèle aucune différence entre les indices. Ma meilleure supposition serait que l'attribution directe à une copie ([:]
) est traitée comme un cas spécial par Pandas, ce qui lui fait ignorer l'index du cessionnaire et créer cette différence.Réponses:
Il y a une très, très grande différence entre
series.iloc[:]
etseries[:]
, lors de l'attribution en retour.(i)loc
vérifie toujours pour s'assurer que tout ce que vous attribuez correspond à l'index du cessionnaire. Pendant ce temps, la[:]
syntaxe est affectée au tableau NumPy sous-jacent, contournant l'alignement d'index.Maintenant que vous comprenez la différence, regardons ce qui se passe dans votre code. Imprimez simplement le RHS de vos boucles pour voir ce que vous attribuez:
Lors de l'affectation à
b_df.iloc[i, :]
la deuxième itération, les index sont différents, donc rien n'est attribué et vous ne voyez que les NaN. Cependant, la modificationb_df.iloc[i, :]
deb_df.iloc[i][:]
signifie que vous affectez au tableau NumPy sous-jacent, donc l'alignement d'indexation est ignoré. Cette opération est mieux exprimée commeIl convient également de mentionner qu'il s'agit d'une forme d'affectation chaînée, ce qui n'est pas une bonne chose , et rend également votre code plus difficile à lire et à comprendre.
la source
[:]
syntaxe assigne au tableau NumPy sous-jacent"?La différence est que dans le premier cas, l'interpréteur Python a exécuté le code comme:
où la valeur serait le côté droit de l'équation. Alors que dans le second cas, l'interpréteur Python a exécuté le code comme:
où encore la valeur serait le côté droit de l'équation.
Dans chacun de ces deux cas, une méthode différente serait appelée à l'intérieur de setitem en raison de la différence entre les clés (i, tranche (Aucun)) et tranche (Aucun) Par conséquent, nous avons un comportement différent.
la source
b_df.iloc[i]
etb_df.iloc[i][:]
ont cependant les mêmes indices. Pourquoi pouvez-vous attribuer une série avec un index non correspondant à l'une mais pas à l'autre?La différence entre
.iloc[i,:]
et.iloc[i][:]
Dans le cas où
.iloc[i,:]
vous accédez directement à une possession spécifique de laDataFrame
, en sélectionnant toutes les (:
) colonnes de lai
e ligne. Pour autant que je sache, il est équivalent de laisser la 2ème dimension non spécifiée (.iloc[i]
).Dans le cas où
.iloc[i][:]
vous effectuez 2 opérations en chaîne. Ainsi, le résultat de.iloc[i]
sera alors affecté par[:]
. L'utilisation de ceci pour définir des valeurs est déconseillée par Pandas lui-même ici avec un avertissement, vous ne devez donc pas l'utiliser:Comme @Scott l'a mentionné dans les commentaires OP, l'alignement des données est intrinsèque , donc les index dans le côté droit du
=
ne seront pas inclus s'ils ne sont pas présents dans le côté gauche. C'est pourquoi il y a desNaN
valeurs sur la 2ème ligne.Donc, pour que les choses soient claires, vous pouvez procéder comme suit:
Ou vous pouvez convertir en au
list
lieu d'utiliserreset_index
:la source