Ich bin so verwirrt mit verschiedenen Indizierungsmethoden, die iloc
in Pandas verwendet werden.
Angenommen, ich versuche, einen 1-D-Datenrahmen in einen 2-D-Datenrahmen zu konvertieren. Zuerst habe ich den folgenden 1-D-Datenrahmen
a_array = [1,2,3,4,5,6,7,8]
a_df = pd.DataFrame(a_array).T
Und ich werde das in einen 2D-Datenrahmen mit der Größe von konvertieren 2x4
. Ich beginne mit der Voreinstellung des 2D-Datenrahmens wie folgt:
b_df = pd.DataFrame(columns=range(4),index=range(2))
Dann benutze ich die for-Schleife, um a_df
(1-d) in b_df
(2-d) mit dem folgenden Code zu konvertieren
for i in range(2):
b_df.iloc[i,:] = a_df.iloc[0,i*4:(i+1)*4]
Es gibt mir nur die folgenden Ergebnisse
0 1 2 3
0 1 2 3 4
1 NaN NaN NaN NaN
Aber wenn ich geändert b_df.iloc[i,:]
zu b_df.iloc[i][:]
. Das Ergebnis ist wie folgt korrekt, was ich will
0 1 2 3
0 1 2 3 4
1 5 6 7 8
Könnte mir jemand erklären, was der Unterschied zwischen .iloc[i,:]
und .iloc[i][:]
ist und warum .iloc[i][:]
in meinem obigen Beispiel funktioniert hat, aber nicht.iloc[i,:]
b_df.iloc[1] = a_df.iloc[0, 4:8]
weist einer Reihe mit Index[4, 5, 6, 7]
eine Reihe mit Index zu[0, 1, 2, 3]
. Es gibt keine Überlappung, daher werdenNaN
alle Elemente zugewiesen. Bis zu diesem Punkt macht es für mich Sinn. Aber wie Sie ist mir nicht klar, warum ich michb_df.iloc[1][:] = ...
anders verhalte - ich untersuche die Objekteb_df.iloc[1]
undb_df.iloc[1][:]
zeige keinen Unterschied zwischen den Indizes. Meine beste Vermutung wäre, dass das direkte Zuweisen zu einer Kopie ([:]
) von Pandas als Sonderfall behandelt wird, wodurch der Index des Empfängers ignoriert wird und diese Diskrepanz entsteht.Antworten:
Es gibt einen sehr, sehr großen Unterschied zwischen
series.iloc[:]
undseries[:]
, wenn zurück zugewiesen wird.(i)loc
Überprüft immer, ob das, was Sie zuweisen, mit dem Index des Empfängers übereinstimmt. In der Zwischenzeit wird die[:]
Syntax dem zugrunde liegenden NumPy-Array zugewiesen, wobei die Indexausrichtung umgangen wird.Nachdem Sie den Unterschied verstanden haben, schauen wir uns an, was in Ihrem Code passiert. Drucken Sie einfach die RHS Ihrer Schleifen aus, um zu sehen, was Sie zuweisen:
Bei der Zuweisung
b_df.iloc[i, :]
in der zweiten Iteration sind die Indizes unterschiedlich, sodass nichts zugewiesen wird und Sie nur NaNs sehen. Wenn Sie jedoch zu ändernb_df.iloc[i, :]
,b_df.iloc[i][:]
werden Sie dem zugrunde liegenden NumPy-Array zugewiesen, sodass die Indizierungsausrichtung umgangen wird. Diese Operation wird besser ausgedrückt alsErwähnenswert ist auch, dass dies eine Form der verketteten Zuweisung ist, was nicht gut ist und das Lesen und Verstehen Ihres Codes erschwert.
quelle
[:]
Syntax wird dem zugrunde liegenden NumPy-Array zugewiesen"?Der Unterschied besteht darin, dass der Python-Interpreter im ersten Fall den Code wie folgt ausgeführt hat:
wobei der Wert die rechte Seite der Gleichung wäre. Während im zweiten Fall der Python-Interpreter den Code wie folgt ausführte:
wo wiederum der Wert die rechte Seite der Gleichung wäre.
In jedem dieser beiden Fälle würde aufgrund des Unterschieds zwischen den Schlüsseln (i, Slice (Keine)) und Slice (Keine) eine andere Methode innerhalb des Setitems aufgerufen. Daher haben wir ein unterschiedliches Verhalten.
quelle
b_df.iloc[i]
undb_df.iloc[i][:]
haben die gleichen Indizes. Warum können Sie einer Reihe eine Reihe mit nicht übereinstimmendem Index zuweisen, der anderen jedoch nicht?Der Unterschied zwischen
.iloc[i,:]
und.iloc[i][:]
Im Falle der
.iloc[i,:]
Sie direkt zu einem bestimmten possition des zugreifenDataFrame
, indem Sie alle (:
) Spalten deri
ten Zeile. Soweit ich weiß, ist es gleichbedeutend, die 2. Dimension nicht spezifiziert zu lassen (.iloc[i]
).Wenn
.iloc[i][:]
Sie 2 verkettete Operationen ausführen. Das Ergebnis von.iloc[i]
wird dann also von beeinflusst[:]
. Die Verwendung dieser Option zum Festlegen von Werten wird von Pandas selbst hier mit einer Warnung nicht empfohlen. Sie sollten sie daher nicht verwenden:Wie @Scott in den OP-Kommentaren erwähnt hat, ist die Datenausrichtung intrinsisch , sodass die Indizes auf der rechten Seite von
=
nicht berücksichtigt werden, wenn sie nicht auf der linken Seite vorhanden sind. Aus diesem Grund befinden sichNaN
in der 2. Zeile Werte.Um die Dinge klar zu lassen, können Sie Folgendes tun:
Oder Sie können konvertieren zu
list
anstatt zu verwendenreset_index
:quelle