Zum Inhalt
wannacode

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:

PythonDaten: die Tabellen des Shops

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“:

PythonDaten: die Tabellen des Shops
  • 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:

PythonDaten: die Tabellen des Shops

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:

PythonDaten: die Tabellen des Shops

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.

1. Der Index ist der Standardindex (0, 1, 2 …). Wie viele Zeilen liefern products.loc[2:5] und products.iloc[2:5]?

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.

PythonDaten: die Tabellen des Shops

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?

PythonDaten: die Tabellen des Shops

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:

PythonDaten: die Tabellen des Shops

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:

PythonDaten: die Tabellen des Shops

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.

PythonDaten: die Tabellen des Shops

Ü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.

PythonDaten: die Tabellen des Shops

Test

Teste dich

1. Welcher Ausdruck liefert eine Tabelle (DataFrame) mit den Spalten name und price?
2. Der Index sind die Produktnamen. Was liefert by_name.loc['Weißkäse', 'price']?
3. products.loc[17, 'stock'] liefert 33, aber der Kaffee (id 17) hat 15 Packungen. Warum?
4. In pandas 3: short = products.loc[low], dann short['stock'] = 30. Was passiert mit products?

Erstellt von Ivo Gergov im Rahmen der Kampagne von Evo Tech für zugängliche Programmierausbildung ·