Was ist der Unterschied zwischen der Verwendung von loc und der Verwendung von nur eckigen Klammern zum Filtern nach Spalten in Pandas / Python?

77

Ich habe drei Methoden zum Auswählen einer Spalte in einem Pandas DataFrame festgestellt:

Erste Methode zur Auswahl einer Spalte mit loc:

df_new = df.loc[:, 'col1']

Zweite Methode - scheint einfacher und schneller:

df_new = df['col1']

Dritte Methode - am bequemsten:

df_new = df.col1

Gibt es einen Unterschied zwischen diesen drei Methoden? Ich glaube nicht. In diesem Fall würde ich lieber die dritte Methode anwenden.

Ich bin meistens neugierig, warum es drei Methoden gibt, um dasselbe zu tun.

Sean McCarthy
quelle
1
Oder was ist mit df.col1? Alle drei sind im Wesentlichen gleichwertig für den sehr einfachen Fall der Auswahl einer Spalte. .locDamit können Sie viel mehr tun, als nur eine Spalte auszuwählen. Mögliches Duplikat von stackoverflow.com/questions/31593201/…
juanpa.arrivillaga
1
Sie machen dasselbe für einfache Scheiben. loc ist expliziter, insbesondere wenn Ihre Spalten Zahlen sind.
Gabriel A
Danke @ juanpa.arrivillaga. Guter Punkt zu: df.col1, einer weiteren Methode zur Spaltenauswahl. Ich habe mir diese andere Frage schon mehrmals angesehen. Es ist großartig, um loc und iloc zu erklären. Bei dieser Frage geht es jedoch um die andere Methode: "df ['col1']". Ich bin nur verwirrt darüber, warum es zwei (oder drei) äquivalente Möglichkeiten gibt, das zu tun, was anscheinend dasselbe ist.
Sean McCarthy
1
Der große Nachteil der 3. Methode ist, dass sie nicht eindeutig ist, wenn Ihr Spaltenname mit einem vorhandenen Pandas-Attribut oder einer vorhandenen Pandas-Methode identisch ist. ZB nennen Sie eine Spalte 'Summe'. df.sumWas passiert dann, wenn Sie tippen ? (Spoiler-Alarm, nichts Nützliches, obwohl es zum df.sum()Glück immer noch funktioniert) Der 3. Weg sollte also als Abkürzung angesehen werden, die in Ordnung ist, aber vorsichtig sein muss
JohnE
1
Eine anständige Erklärung hier stackoverflow.com/questions/38886080/…
Gaurav Taneja

Antworten:

79

In den folgenden Situationen verhalten sie sich gleich:

  1. Eine einzelne Spalte auswählen ( df['A']die gleichen wie df.loc[:, 'A']-> wählt Spalte A)
  2. Auswählen einer Liste von Spalten ( df[['A', 'B', 'C']]die gleiche wie df.loc[:, ['A', 'B', 'C']]-> wählt die Spalten A, B und C)
  3. Slicing von Reihen ( df[1:3]ist das gleiche wie df.iloc[1:3]-> wählt die Zeilen 1 und 2. Beachten Sie jedoch, wenn Sie Zeilen mit in Scheiben schneiden loc, statt iloc. Sie werden die Zeilen 1 bekommen, 2 und 3 unter der Annahme , Sie RandeIndex haben Details sehen hier .)

Funktioniert jedoch []nicht in den folgenden Situationen:

  1. Sie können eine einzelne Zeile mit auswählen df.loc[row_label]
  2. Sie können eine Liste von Zeilen mit auswählen df.loc[[row_label1, row_label2]]
  3. Sie können Spalten mit schneiden df.loc[:, 'A':'C']

Diese drei können nicht erledigt werden []. Noch wichtiger ist, dass die Zuweisung problematisch wird, wenn Ihre Auswahl sowohl Zeilen als auch Spalten umfasst.

df[1:3]['A'] = 5

Dies wählt die Zeilen 1 und 2 aus, wählt dann die Spalte 'A' des zurückkehrenden Objekts aus und weist ihm den Wert 5 zu. Das Problem ist, dass das zurückgebende Objekt möglicherweise eine Kopie ist, sodass der tatsächliche DataFrame dadurch möglicherweise nicht geändert wird. Dies löst SettingWithCopyWarning aus . Der richtige Weg für diese Zuordnung ist

df.loc[1:3, 'A'] = 5

Mit .locwird garantiert, dass Sie den ursprünglichen DataFrame ändern. Außerdem können Sie Spalten ( df.loc[:, 'C':'F']) in Scheiben schneiden , eine einzelne Zeile ( df.loc[5]) auswählen und eine Liste von Zeilen ( df.loc[[1, 2, 5]]) auswählen .

Beachten Sie auch, dass diese beiden nicht gleichzeitig in der API enthalten waren. .locwurde viel später als leistungsfähigerer und expliziter Indexer hinzugefügt. Weitere Informationen finden Sie in der Antwort von unutbu .


Hinweis: Das Abrufen von Spalten mit []vs .ist ein völlig anderes Thema. .ist nur zur Bequemlichkeit da. Es ist nur der Zugriff auf Spalten möglich, deren Name eine gültige Python-Kennung ist (dh sie dürfen keine Leerzeichen enthalten, sie können nicht aus Zahlen bestehen ...). Es kann nicht verwendet werden, wenn die Namen mit Series / DataFrame-Methoden in Konflikt stehen. Es kann auch nicht für nicht vorhandene Spalten verwendet werden (dh die Zuweisung df.a = 1funktioniert nicht, wenn keine Spalte vorhanden ist a). Davon abgesehen .und []sind gleich.

Ayhan
quelle
6

locist besonders nützlich, wenn der Index nicht numerisch ist (z. B. ein DatetimeIndex), da Sie Zeilen mit bestimmten Beschriftungen aus dem Index abrufen können :

df.loc['2010-05-04 07:00:00']
df.loc['2010-1-1 0:00:00':'2010-12-31 23:59:59 ','Price']

Es []ist jedoch beabsichtigt, Spalten mit bestimmten Namen zu erhalten:

df['Price']

Mit können []Sie auch Zeilen filtern , aber es ist ausführlicher:

df[df['Date'] < datetime.datetime(2010,1,1,7,0,0)]['Price']
Freeman
quelle
0

Es scheint einen Unterschied zwischen df.loc [] und df [] zu geben, wenn Sie einen Datenrahmen mit mehreren Spalten erstellen.

Sie können sich auf diese Frage beziehen: Gibt es eine gute Möglichkeit, mit .loc mehrere Spalten zu generieren?

Hier können Sie nicht mehrere Spalten mit generieren, df.loc[:,['name1','name2']]sondern nur mit doppelter Klammer df[['name1','name2']]. (Ich frage mich, warum sie sich anders verhalten.)

Matthew Son
quelle