Auswählen: [], loc und iloc
Kurz gesagt: In pandas wählt [] Spalten, loc wählt Zeilen und Zellen nach Beschriftung, und iloc wählt sie nach Position.
Problem
„Der Käse wird teurer“
Der Lieferant erhöht den Preis des Weißkäses von 7,90 € auf 8,40 €. Der Chef will drei Dinge:
- eine kleine Tabelle für die Theke, nur mit Name und Preis;
- Preis und Bestand eines Produkts, ohne mit dem Auge zu suchen;
- den neuen Preis in der Tabelle, nicht in irgendeiner Kopie nebenher.
Das ist Auswählen: einen Teil der Tabelle nehmen, Spalten, Zeilen oder eine Zelle, und ihn manchmal ändern. pandas hat dafür drei Werkzeuge: [], loc und iloc.
Die Idee
Spalten: []
Eine Spalte nimmst du schon mit []. Setzt du eine Liste von Namen in die Klammern, bekommst du eine Tabelle mit diesen Spalten, in dieser Reihenfolge:
Ein Name liefert eine Series mit der Form (25,). Eine Liste liefert einen DataFrame mit der Form (25, 2), auch wenn die Liste eine Spalte hat: products[['price']] ist eine Tabelle. Die doppelten Klammern sind keine besondere Syntax: Die äußeren sind zum Auswählen, die inneren für die Liste.
Die Idee
Nach Beschriftung: loc
loc wählt nach Beschriftungen: zuerst die Zeilen, dann die Spalten, durch ein Komma getrennt. Mit den Namen im Index heißt das „Zeile Weißkäse, Spalte price“:
- Eine Zeile und eine Spalte liefern eine Zelle: 7.9.
- Eine Zeile allein liefert die ganze Zeile als Series. Ihre Beschriftungen sind jetzt die Namen der Spalten.
- Listen liefern eine Tabelle: der Käse und die Butter mit Preis und Bestand.
Sieh es dir an
Ein Slice mit loc schließt das Ende ein
Ein Slice mit Doppelpunkt (start:stop) funktioniert auch in loc, aber es gibt einen Unterschied, der jeden verwirrt:
loc[0:3] liefert 4 Namen: von Beschriftung 0 bis Beschriftung 3 einschließlich. Ein Slice von Positionen (iloc, Python-Listen) hört vor dem Ende auf und liefert 3.
Der Grund sind die Beschriftungen. Mit Namen im Index liefert loc['Frischmilch':'Butter'] die Milchprodukte, von der Milch bis zur Butter. Niemand wollte die Butter weglassen, nur weil sie zuletzt steht. Wie würdest du „bis kurz nach der Butter“ schreiben?
Die Idee
Nach Position: iloc
iloc wählt nach Position, wie ein NumPy-Array: Die erste Zeile ist 0, die letzte -1. Die Beschriftungen spielen keine Rolle:
iloc[0, 1] ist die erste Zeile, zweite Spalte: „Weißbrot“. iloc[-1, 1] ist das letzte Produkt: die Geschenkkarte. iloc[:3, [1, 3]] sind die ersten drei Zeilen, die Spalten an den Plätzen 1 und 3.
Was wann? loc, wenn du weißt, was du suchst: ein Produkt, eine Spalte nach Namen. iloc, wenn es dir um den Platz geht: die ersten 5, die letzte Zeile. Positionen verschieben sich, sobald die Tabelle sortiert oder zerschnitten wird, Beschriftungen bleiben.
Probier es aus
Kaffee im Lager
Kaffee ist das Produkt mit der id 17. Wie viele Packungen sind auf Lager? Lege id in den Index (by_id) und lege den Bestand als eine Zahl in coffee_stock ab.
Lösung
import pandas as pd
products = pd.read_csv('products.csv')
by_id = products.set_index('id')
coffee_stock = by_id.loc[17, 'stock']
print(coffee_stock)by_id = products.set_index('id') und coffee_stock = by_id.loc[17, 'stock'] liefert 15. Die Falle ist products.loc[17, 'stock']: Ohne set_index sind die Beschriftungen die Zahlen ab 0, Beschriftung 17 ist die 18. Zeile, der Pfefferminztee, und die Antwort ist 33. Ohne die Spalte (by_id.loc[17]) bekommst du die ganze Zeile, nicht die Zahl.
Die Idee
Eine Kopie oder dieselbe Tabelle
Jetzt der neue Preis. Du schneidest die Milchprodukte heraus und änderst darin den Preis des Käses. Ändert sich products?
Nein: In dairy ist der Käse 8.4, in products aber noch 7.9. In pandas 3 verhält sich jedes herausgeschnittene Stück wie eine Kopie. Das Ändern des Stücks berührt das Original nicht. Das heißt Copy-on-Write: pandas kopiert die Daten nicht sofort, sondern erst, wenn eines der beiden Objekte sich ändert.
Um die Tabelle zu ändern, schreibst du in die Tabelle selbst, mit loc und Zeile und Spalte auf einmal: products.loc[6, 'price'] = 8.4.
Sieh es dir an
Zwei Klammern hintereinander schreiben nicht
Die Versuchung ist products['price'][6] = 8.4: die Spalte, dann die Zelle. Es sieht aus wie loc, ist aber nicht dasselbe:
Der Preis ist weiterhin 7.9. products['price'] ist ein eigenes Objekt, eine Kopie, und [6] = 8.4 schreibt hinein. Das heißt verkettete Zuweisung (chained assignment). pandas 3 wendet sie nie auf die Tabelle an und zeigt eine Warnung ChainedAssignmentError mit einem Hinweis auf .loc.
Es gibt eine Regel: Du schreibst mit einem einzigen loc[Zeile, Spalte] = … auf die Tabelle, die du ändern willst.
Genauer, für Neugierige
In pandas 1 und 2 änderte derselbe Code die Tabelle manchmal und manchmal nicht, je nachdem, ob darunter eine Kopie oder eine Sicht lag. Deshalb gab es eine SettingWithCopyWarning, die „vielleicht“ sagte. Du triffst sie in alten Artikeln und in Antworten im Netz. In pandas 3 (2026) ist die Regel klar, und die Warnung ist Geschichte. Muss dein Code auch auf einer alten Version laufen, ist loc in einem Schritt dort ebenfalls richtig.
Die Idee
Viele Zeilen auf einmal: eine Maske in loc
An die Stelle der Zeilen in loc kannst du eine Maske setzen: eine Spalte aus True und False, wie die Masken in NumPy. Dann gilt die Änderung für jede Zeile, in der die Maske True ist. Zwei Produkte sind ausverkauft, und eine Lieferung von je 30 kommt:
empty.sum() zählt die leeren: 2. Nach der loc-Zeile haben die Banitsa und die Gurken je 30. Masken auf einer Tabelle brauchen wir in der nächsten Lektion bei den Filtern noch oft.
Probier es aus
Lieferung für die fast leeren
Jedes Produkt mit weniger als 10 auf Lager bekommt 20 dazu. Lege die Maske in low ab und ändere dann ihren Bestand in products.
Lösung
import pandas as pd
products = pd.read_csv('products.csv')
low = products['stock'] < 10
products.loc[low, 'stock'] = products.loc[low, 'stock'] + 20
print(products.loc[low, ['name', 'stock']])low = products['stock'] < 10 erfasst 4 Produkte, und products.loc[low, 'stock'] = products.loc[low, 'stock'] + 20 füllt sie auf: Die Banitsa und die Gurken werden 20, die Bratpfanne 28 und die Messer 25. Schneidest du short = products.loc[low] heraus und änderst es, bleibt products gleich. Die Kette products['stock'][low] = … schreibt ebenfalls nicht in die Tabelle.
Übung
Die Tabelle für die Theke
Die Namen stehen im Index von by_name. Ändere in by_name den Preis von Weißkäse auf 8.4. Lege dann in counter die Tabelle für die Theke ab: die Milchprodukte von Frischmilch bis Butter, mit den Spalten price und stock.
Lösung
import pandas as pd
products = pd.read_csv('products.csv')
by_name = products.set_index('name')
by_name.loc['Weißkäse', 'price'] = 8.4
counter = by_name.loc['Frischmilch':'Butter', ['price', 'stock']]
counterby_name.loc['Weißkäse', 'price'] = 8.4 schreibt in die Tabelle. counter = by_name.loc['Frischmilch':'Butter', ['price', 'stock']] liefert 5 Zeilen einschließlich der Butter, weil loc das Ende einschließt. Mit iloc[4:8] fehlt die Butter. Änderst du den Preis in counter oder mit by_name['price']['Weißkäse'], zeigen die Theke und das Lager verschiedene Preise, und by_name behält den alten.
Test
Teste dich
Verwandte Lektionen
Abschnitt „Verwandte Lektionen“- Baut auf: Die erste Tabelle · Vektorisierung · Series und DataFrame
- Geht weiter in: Filtern und Sortieren · Neue Spalten · Typen und fehlende Werte · Gruppen: groupby
- Aufgaben zum Thema: Tabellen mit pandas