Unterschied iloc und loc

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
nichtSoGuter
User
Beiträge: 92
Registriert: Mittwoch 13. April 2022, 17:40

Hallo,

ich habe einen code geschrieben bei dem ich bei iloc eine Fehlermeldung "SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame".
Bei loc erhalte ich diese Fehlermeldung nicht.
Woran liegt das?

Soweit ich weiß kann man mit beiden methoden Zeilen und Spalten ansprechen. Dabei spricht man bei loc die zeile oder spalte mit dem Namen, bei iloc mit dem index der zeile oder Spalte. Beide returnen beide keine Kopie der zeile/ spalte sondern Sprechen diese nur an.

also verstehe ich nicht wie es sein kann das ich bei einer die fehlermeldung erhalte bei der anderen aber nicht.

Mein code

Code: Alles auswählen

from sklearn.model_selection import StratifiedShuffleSplit
# Instanz von StratifiedShuffleSplit legt fest wie aufgeteilt werden soll
aufteilung = StratifiedShuffleSplit(n_splits=1, test_size = 0.2, random_state=42)

# Aufteilung mit einer forSchleife anhand von Indexen
for test_index, train_index in aufteilung.split(daten, daten["Einkommensgruppen"]):
    trainingsdaten = daten.iloc[train_index]                                                                              # hier  iloc / loc verwendet
    testdaten = daten.iloc[test_index]
testDataFrame = pd.DataFrame(trainingsdaten)
trainingsdaten

# die zusätzliche Spalte "Einkommensgruppen" aus beiden Daten entfernen
trainingsdaten.drop("Einkommensgruppen", axis =1, inplace =True)                                # hier wird fehlermeldung angezeigt
testdaten.drop("Einkommensgruppen", axis =1, inplace =True)
Vielen Dank im Voraus!
Benutzeravatar
__blackjack__
User
Beiträge: 14078
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@nichtSoGuter: Offenbar wird dort doch eine Kopie erstellt, darum ja auch die Warnung.

Die Schleife sieht auch sinnlos aus, weil da am Ende ja nur die letzten Zuweisungen wirklich einen Effekt haben, warum wird dann eine Schleife ausgeführt?

Ist das `inplace` wirklich notwendig?
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
nichtSoGuter
User
Beiträge: 92
Registriert: Mittwoch 13. April 2022, 17:40

Vielen Dank für Ihre Rückmeldung!

so wie ich das verstanden habe gibt die .split() methode indices zurück, womit dann die Daten in trainings und testdaten aufgeteilt werden können. mit der for schleife werden diese Indices iteriert und die die Daten mit (siehe code unten)

Code: Alles auswählen

     trainingsdaten = daten.iloc[train_index]                                                                       
    testdaten = daten.iloc[test_index]
in trainingsdaten und testdaten aufgeteilt. Wie würden Sie das ohne eine for Schleife anstellen?

und so wie ich das verstehe wird mit inplace=True keine kopie zurückgegeben, sondern die Daten verändert. Genau das war auch mein Ziel. Oder habe ich das Falsch verstanden?
Benutzeravatar
__blackjack__
User
Beiträge: 14078
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@nichtSoGuter: Die `split()`-Methode gibt etwas zurück wovon nur das letzte verwendet wird, weil die Schleife ja über alle Elemente läuft, aber nur der letzte Schleifendurchlauf effektiv Werte an die beiden Namen bindet. Da ist die Frage ob das so gewollt ist. Falls ja würde ich das entweder anders machen oder zumindest kommentieren warum das so komisch gemacht wird.

Welche Daten werden (nicht) verändert? Das ``inplace=True`` sorgt dafür das *die* Daten auf die das angewendet wird verändert werden, aber die selbst sind halt eine Kopie und das führt zu der Warnung. Die wird man los in dem man explizit vorher eine Kopie erstellt, oder eben bei diesem Schritt das ``inplace=True`` weg lässt (und dann natürlich das Ergebnis an einen Namen bindet).
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Antworten