it-swarm.com.de

pandas loc vs. iloc vs. ix vs. at vs. iat?

Seit kurzem verzweige ich von meinem sicheren Ort (R) nach Python und bin etwas verwirrt über die Zelllokalisierung/-auswahl in Pandas. Ich habe die Dokumentation gelesen, aber ich Ich habe Mühe, die praktischen Auswirkungen der verschiedenen Lokalisierungs-/Auswahloptionen zu verstehen.

  • Gibt es einen Grund, warum ich jemals .loc Oder .iloc Für die allgemeinste Option .ix Verwenden sollte?
  • Ich verstehe, dass .loc, iloc, at und iat eine garantierte Richtigkeit liefern können, die .ix Nicht bieten kann, aber ich habe auch gelesen, wo .ix die schnellste Lösung auf der ganzen Linie ist.
  • Bitte erläutern Sie die realen Best Practices, die dahinter stehen, etwas anderes als .ix Zu verwenden.
149
user4613042

loc: nur mit Index arbeiten
iloc: Arbeit an der Position
ix: Sie können Daten von Datenrahmen abrufen, ohne dass sie im Index enthalten sind
at: Skalarwerte erhalten. Es ist eine sehr schnelle Lok
iat: Liefert skalare Werte. Es ist ein sehr schneller iloc

http://pyciencia.blogspot.com/2015/05/obtener-y-filtrar-datos-de-un-dataframe.html

Hinweis: Stand pandas 0.20.0, das .ix Indexer ist veraltet zugunsten der strengeren .iloc und .loc Indexer.

122
lautremont

Aktualisiert für pandas0.20 da ix veraltet ist. Dies zeigt nicht nur, wie Sie loc, iloc, at, iat, set_value, aber wie erreicht man eine gemischte positions-/etikettenbasierte Indizierung?.


loc - label based
Ermöglicht das Übergeben von 1-D-Arrays als Indexer. Arrays können entweder Slices (Teilmengen) des Index oder der Spalte sein oder boolesche Arrays, deren Länge dem Index oder den Spalten entspricht.

Besonderer Hinweis: Wenn ein skalarer Indexer übergeben wird, kann loc einen neuen Index- oder Spaltenwert zuweisen, der zuvor nicht existiert hat.

# label based, but we can use position values
# to get the labels from the index object
df.loc[df.index[2], 'ColName'] = 3

df.loc[df.index[1:3], 'ColName'] = 3

iloc - positionsbasiert
Ähnlich wie loc, außer dass Positionen anstelle von Indexwerten verwendet werden. Sie können jedoch keine neuen Spalten oder Indizes zuweisen .

# position based, but we can get the position
# from the columns object via the `get_loc` method
df.iloc[2, df.columns.get_loc('ColName')] = 3

df.iloc[2, 4] = 3

df.iloc[:3, 2:4] = 3

at - label based
Funktioniert sehr ähnlich wie loc für skalare Indexer. Auf Array-Indexern kann nicht gearbeitet werden. Kann! neue Indizes und Spalten zuweisen.

Vorteil gegenüber loc ist, dass dies schneller ist.
Nachteil ist, dass Sie keine Arrays für Indexer verwenden können.

# label based, but we can use position values
# to get the labels from the index object
df.at[df.index[2], 'ColName'] = 3

df.at['C', 'ColName'] = 3

iat - positionsbasiert
Funktioniert ähnlich wie iloc. Kann in Array-Indexern nicht arbeiten. Kann keine neuen Indizes und Spalten zuweisen! .

Vorteil gegenüber iloc ist, dass dies schneller ist.
Nachteil ist, dass Sie keine Arrays für Indexer verwenden können.

# position based, but we can get the position
# from the columns object via the `get_loc` method
IBM.iat[2, IBM.columns.get_loc('PNL')] = 3

set_value - labelbasiert
Funktioniert sehr ähnlich wie loc für skalare Indexer. Auf Array-Indexern kann nicht gearbeitet werden. Kann! neue Indizes und Spalten zuweisen

Vorteil Super schnell, weil es sehr wenig Overhead gibt!
Nachteil Der Aufwand ist sehr gering, da pandas keine Reihe von Sicherheitsprüfungen durchführt. Verwendung auf eigenes Risiko. Dies ist auch nicht für den öffentlichen Gebrauch bestimmt.

# label based, but we can use position values
# to get the labels from the index object
df.set_value(df.index[2], 'ColName', 3)

set_value mit takable=True - positionsbasiert
Funktioniert ähnlich wie iloc. Kann in Array-Indexern nicht arbeiten. Kann keine neuen Indizes und Spalten zuweisen! .

Vorteil Super schnell, weil es sehr wenig Overhead gibt!
Nachteil Der Aufwand ist sehr gering, da pandas keine Reihe von Sicherheitsprüfungen durchführt. Verwendung auf eigenes Risiko. Dies ist auch nicht für den öffentlichen Gebrauch bestimmt.

# position based, but we can get the position
# from the columns object via the `get_loc` method
df.set_value(2, df.columns.get_loc('ColName'), 3, takable=True)
79
piRSquared

Es gibt zwei Hauptmethoden, mit denen pandas eine Auswahl aus einem DataFrame trifft.

  • Von Label
  • By Integer Location

In der Dokumentation wird der Begriff Position verwendet, um auf Ganzzahlposition zu verweisen. Ich mag diese Terminologie nicht, da ich finde, dass sie verwirrend ist. Ganzzahlige Position ist aussagekräftiger und genau das, wofür .iloc Steht. Das Schlüsselwort hier ist GANZZAHL - Sie müssen Ganzzahlen verwenden, wenn Sie nach Ganzzahlposition auswählen.

Stellen Sie vor dem Anzeigen der Zusammenfassung sicher, dass ...

.ix ist veraltet und mehrdeutig und sollte niemals verwendet werden

Es gibt drei primäre Indexer für Pandas. Wir haben den Indexierungsoperator selbst (die Klammern []), .loc und .iloc. Fassen wir sie zusammen:

  • [] - Wählt hauptsächlich Teilmengen von Spalten aus, kann aber auch Zeilen auswählen. Zeilen und Spalten können nicht gleichzeitig ausgewählt werden.
  • .loc - Wählt nur Teilmengen von Zeilen und Spalten nach Bezeichnung aus
  • .iloc - Wählt Teilmengen von Zeilen und Spalten nur nach ganzzahliger Position aus

Ich verwende fast nie .at oder .iat, da sie keine zusätzlichen Funktionen bieten und nur eine kleine Leistungssteigerung bewirken. Ich würde von ihrer Verwendung abraten, es sei denn, Sie haben eine sehr zeitkritische Anwendung. Unabhängig davon haben wir ihre Zusammenfassung:

  • .at wählt einen einzelnen Skalarwert im DataFrame nur nach Bezeichnung aus
  • .iat wählt einen einzelnen Skalarwert im DataFrame nur nach ganzzahliger Position aus

Zusätzlich zur Auswahl nach Label und ganzzahliger Position gibt es Boolesche Auswahl auch als Boolesche Indizierung bezeichnet.


Beispiele, die .loc, .iloc, Boolesche Auswahl und .at Und .iat Erläutern, sind unten gezeigt

Wir werden uns zuerst auf die Unterschiede zwischen .loc Und .iloc Konzentrieren. Bevor wir auf die Unterschiede eingehen, sollten Sie wissen, dass DataFrames über Bezeichnungen verfügen, mit denen sich jede Spalte und jede Zeile besser identifizieren lässt. Schauen wir uns ein Beispiel für einen DataFrame an:

df = pd.DataFrame({'age':[30, 2, 12, 4, 32, 33, 69],
                   'color':['blue', 'green', 'red', 'white', 'gray', 'black', 'red'],
                   'food':['Steak', 'Lamb', 'Mango', 'Apple', 'Cheese', 'Melon', 'Beans'],
                   'height':[165, 70, 120, 80, 180, 172, 150],
                   'score':[4.6, 8.3, 9.0, 3.3, 1.8, 9.5, 2.2],
                   'state':['NY', 'TX', 'FL', 'AL', 'AK', 'TX', 'TX']
                   },
                  index=['Jane', 'Nick', 'Aaron', 'Penelope', 'Dean', 'Christina', 'Cornelia'])

enter image description here

Alle Wörter in fett ​​sind die Bezeichnungen. Die Bezeichnungen age, color, food, height, score und state werden für die - Spalten. Die anderen Bezeichnungen Jane, Nick, Aaron, Penelope, Dean, Christina, Cornelia werden als Beschriftungen für die Zeilen verwendet. Zusammen werden diese Zeilenbezeichnungen als Index bezeichnet.


Die wichtigsten Methoden zum Auswählen bestimmter Zeilen in einem DataFrame sind die Indexer .loc Und .iloc. Jeder dieser Indexer kann auch zum gleichzeitigen Auswählen von Spalten verwendet werden, es ist jedoch einfacher, sich vorerst nur auf Zeilen zu konzentrieren. Außerdem verwendet jeder der Indexer eine Reihe von Klammern, die unmittelbar hinter dem Namen stehen, um eine Auswahl zu treffen.

.loc wählt Daten nur anhand von Beschriftungen aus

Wir werden zuerst über den Indexer .loc Sprechen, der nur Daten anhand der Index- oder Spaltenbezeichnungen auswählt. In unserem DataFrame-Beispiel haben wir aussagekräftige Namen als Werte für den Index angegeben. Viele DataFrames haben keine aussagekräftigen Namen und verwenden stattdessen standardmäßig nur die Ganzzahlen von 0 bis n-1, wobei n die Länge (Anzahl der Zeilen) des DataFrames ist.

Es gibt viele verschiedene Eingaben Sie können für .loc Drei von ihnen verwenden

  • Ein Faden
  • Eine Liste von Zeichenfolgen
  • Slice-Notation mit Strings als Start- und Stoppwert

Auswahl einer einzelnen Zeile mit .loc mit einem String

Um eine einzelne Datenzeile auszuwählen, setzen Sie die Indexbezeichnung in die Klammern nach .loc.

df.loc['Penelope']

Dies gibt die Datenzeile als Serie zurück

age           4
color     white
food      Apple
height       80
score       3.3
state        AL
Name: Penelope, dtype: object

Auswählen mehrerer Zeilen mit .loc mit einer Liste von Zeichenfolgen

df.loc[['Cornelia', 'Jane', 'Dean']]

Dies gibt einen DataFrame mit den Zeilen in der in der Liste angegebenen Reihenfolge zurück:

enter image description here

Auswählen mehrerer Zeilen mit .loc in Slice-Notation

Die Slice-Notation wird durch Start-, Stopp- und Schrittwerte definiert. Beim Schneiden nach Etikett bezieht pandas den Stoppwert in die Rückgabe ein. Die folgenden Slices von Aaron bis Dean inklusive. Die Schrittgröße ist nicht explizit definiert, sondern standardmäßig auf 1 festgelegt.

df.loc['Aaron':'Dean']

enter image description here

Komplexe Slices können auf dieselbe Weise aufgenommen werden wie Listen mit Python.

.iloc wählt Daten nur nach ganzzahliger Position aus

Wenden wir uns nun .iloc Zu. Jede Datenzeile und -spalte in einem DataFrame hat eine ganzzahlige Position, die sie definiert. Dies ist zusätzlich zu der Beschriftung, die in der Ausgabe visuell angezeigt wird. Die Ganzzahlposition ist einfach die Anzahl der Zeilen/Spalten von oben/links beginnend bei 0.

Es gibt viele verschiedene Eingaben Sie können für .iloc Drei von ihnen verwenden

  • Eine ganze Zahl
  • Eine Liste von ganzen Zahlen
  • Slice-Notation mit Ganzzahlen als Start- und Stoppwert

Auswahl einer einzelnen Zeile mit .iloc mit einer ganzen Zahl

df.iloc[4]

Dies gibt die 5. Zeile (ganzzahlige Position 4) als eine Reihe zurück

age           32
color       gray
food      Cheese
height       180
score        1.8
state         AK
Name: Dean, dtype: object

Mehrere Zeilen mit .iloc mit einer Liste von ganzen Zahlen auswählen

df.iloc[[2, -2]]

Dies gibt einen DataFrame der dritten und vorletzten Zeile zurück:

enter image description here

Auswählen mehrerer Zeilen mit .iloc in Slice-Notation

df.iloc[:5:3]

enter image description here


Gleichzeitige Auswahl von Zeilen und Spalten mit .loc und .iloc

Eine hervorragende Fähigkeit von beiden .loc/.iloc Ist die Fähigkeit, sowohl Zeilen als auch Spalten gleichzeitig auszuwählen. In den obigen Beispielen wurden alle Spalten aus jeder Auswahl zurückgegeben. Wir können Spalten mit denselben Eingabetypen wie für Zeilen auswählen. Wir müssen einfach die Zeilen- und Spaltenauswahl mit einem Komma trennen.

Zum Beispiel können wir die Zeilen Jane und Dean mit nur der Höhe, der Punktzahl und dem Status der Spalten wie folgt auswählen:

df.loc[['Jane', 'Dean'], 'height':]

enter image description here

Dies verwendet eine Liste von Bezeichnungen für die Zeilen und eine Slice-Notation für die Spalten

Wir können natürlich ähnliche Operationen mit .iloc Ausführen, indem wir nur ganze Zahlen verwenden.

df.iloc[[1,4], 2]
Nick      Lamb
Dean    Cheese
Name: food, dtype: object

Gleichzeitige Auswahl mit Bezeichnungen und ganzzahliger Position

.ix Wurde verwendet, um eine Auswahl gleichzeitig mit Beschriftungen und einer Ganzzahlposition zu treffen, was nützlich, aber manchmal verwirrend und mehrdeutig war und zum Glück veraltet war. Für den Fall, dass Sie eine Auswahl mit einer Mischung aus Bezeichnungen und Ganzzahlpositionen treffen müssen, müssen Sie sowohl Ihre Auswahlbezeichnungen als auch Ganzzahlpositionen treffen.

Wenn wir beispielsweise die Zeilen Nick und Cornelia zusammen mit den Spalten 2 und 4 auswählen möchten, können wir .loc Verwenden, indem wir die Ganzzahlen in Bezeichnungen mit den folgenden Werten konvertieren:

col_names = df.columns[[2, 4]]
df.loc[['Nick', 'Cornelia'], col_names] 

Alternativ können Sie die Indexbeschriftungen mit der Indexmethode get_loc In Ganzzahlen konvertieren.

labels = ['Nick', 'Cornelia']
index_ints = [df.index.get_loc(label) for label in labels]
df.iloc[index_ints, [2, 4]]

Boolesche Auswahl

Der .loc-Indexer kann auch eine Boolesche Auswahl vornehmen. Wenn wir beispielsweise alle Zeilen mit einem Alter von mehr als 30 Jahren suchen und nur die Spalten food und score zurückgeben möchten, können wir Folgendes tun:

df.loc[df['age'] > 30, ['food', 'score']] 

Sie können dies mit .iloc Replizieren, es kann jedoch keine Boolesche Reihe übergeben werden. Sie müssen die Boolesche Reihe in ein Numpy-Array wie folgt konvertieren:

df.iloc[(df['age'] > 30).values, [2, 4]] 

Auswahl aller Zeilen

Es ist möglich, .loc/.iloc Nur für die Spaltenauswahl zu verwenden. Sie können alle Zeilen mit einem Doppelpunkt wie folgt auswählen:

df.loc[:, 'color':'score':2]

enter image description here


Der Indizierungsoperator [] Kann auch Zeilen und Spalten aufteilen, jedoch nicht gleichzeitig.

Die meisten Benutzer kennen den Hauptzweck des DataFrame-Indizierungsoperators, nämlich die Auswahl von Spalten. Eine Zeichenfolge wählt eine einzelne Spalte als Serie aus, und eine Liste von Zeichenfolgen wählt mehrere Spalten als DataFrame aus.

df['food']

Jane          Steak
Nick           Lamb
Aaron         Mango
Penelope      Apple
Dean         Cheese
Christina     Melon
Cornelia      Beans
Name: food, dtype: object

Wenn Sie eine Liste verwenden, werden mehrere Spalten ausgewählt

df[['food', 'score']]

enter image description here

Weniger bekannt ist, dass bei Verwendung der Slice-Notation die Auswahl nach Zeilenbeschriftungen oder nach ganzzahliger Position erfolgt. Das ist sehr verwirrend und etwas, das ich fast nie benutze, aber es funktioniert.

df['Penelope':'Christina'] # slice rows by label

enter image description here

df[2:6:2] # slice rows by integer location

enter image description here

Die explizite Angabe von .loc/.iloc Für die Auswahl von Zeilen wird dringend empfohlen. Der Indizierungsoperator allein kann nicht gleichzeitig Zeilen und Spalten auswählen.

df[3:5, 'color']
TypeError: unhashable type: 'slice'

Auswahl durch .at Und .iat

Die Auswahl mit .at Ist nahezu identisch mit .loc, Wählt jedoch nur eine einzelne 'Zelle' in Ihrem DataFrame aus. Wir bezeichnen diese Zelle normalerweise als Skalarwert. Übergeben Sie zur Verwendung von .at Eine durch Komma getrennte Zeilen- und Spaltenbezeichnung.

df.at['Christina', 'color']
'black'

Die Auswahl mit .iat Ist nahezu identisch mit .iloc, Wählt jedoch nur einen einzelnen Skalarwert aus. Sie müssen sowohl für die Zeilen- als auch für die Spaltenposition eine Ganzzahl übergeben

df.iat[2, 5]
'FL'
48
Ted Petrou
df = pd.DataFrame({'A':['a', 'b', 'c'], 'B':[54, 67, 89]}, index=[100, 200, 300])

df

                        A   B
                100     a   54
                200     b   67
                300     c   89
In [19]:    
df.loc[100]

Out[19]:
A     a
B    54
Name: 100, dtype: object

In [20]:    
df.iloc[0]

Out[20]:
A     a
B    54
Name: 100, dtype: object

In [24]:    
df2 = df.set_index([df.index,'A'])
df2

Out[24]:
        B
    A   
100 a   54
200 b   67
300 c   89

In [25]:    
df2.ix[100, 'a']

Out[25]:    
B    54
Name: (100, a), dtype: int64
31
Lydia

Beginnen wir mit diesem kleinen df:

import pandas as pd
import time as tm
import numpy as np
n=10
a=np.arange(0,n**2)
df=pd.DataFrame(a.reshape(n,n))

Wir werden es so haben

df
Out[25]: 
        0   1   2   3   4   5   6   7   8   9
    0   0   1   2   3   4   5   6   7   8   9
    1  10  11  12  13  14  15  16  17  18  19
    2  20  21  22  23  24  25  26  27  28  29
    3  30  31  32  33  34  35  36  37  38  39
    4  40  41  42  43  44  45  46  47  48  49
    5  50  51  52  53  54  55  56  57  58  59
    6  60  61  62  63  64  65  66  67  68  69
    7  70  71  72  73  74  75  76  77  78  79
    8  80  81  82  83  84  85  86  87  88  89
    9  90  91  92  93  94  95  96  97  98  99

Damit haben wir:

df.iloc[3,3]
Out[33]: 33

df.iat[3,3]
Out[34]: 33

df.iloc[:3,:3]
Out[35]: 
    0   1   2   3
0   0   1   2   3
1  10  11  12  13
2  20  21  22  23
3  30  31  32  33



df.iat[:3,:3]
Traceback (most recent call last):
   ... omissis ...
ValueError: At based indexing on an integer index can only have integer indexers

Daher können wir .iat nicht für Teilmengen verwenden, bei denen wir nur .iloc verwenden müssen.

Aber lassen Sie uns beide versuchen, aus einem größeren df auszuwählen und die Geschwindigkeit zu überprüfen ...

# -*- coding: utf-8 -*-
"""
Created on Wed Feb  7 09:58:39 2018

@author: Fabio Pomi
"""

import pandas as pd
import time as tm
import numpy as np
n=1000
a=np.arange(0,n**2)
df=pd.DataFrame(a.reshape(n,n))
t1=tm.time()
for j in df.index:
    for i in df.columns:
        a=df.iloc[j,i]
t2=tm.time()
for j in df.index:
    for i in df.columns:
        a=df.iat[j,i]
t3=tm.time()
loc=t2-t1
at=t3-t2
prc = loc/at *100
print('\nloc:%f at:%f prc:%f' %(loc,at,prc))

loc:10.485600 at:7.395423 prc:141.784987

Mit .loc können wir also Teilmengen und mit .at nur einen einzelnen Skalar verwalten, aber .at ist schneller als .loc

:-)

4
Fabio Pomi