Czy ktoś może wyjaśnić, czym różnią się te trzy metody krojenia?
Widziałem dokumenty i widziałem te odpowiedzi , ale wciąż nie jestem w stanie wyjaśnić, jak te trzy są różne. Wydają mi się one w dużej mierze wymienne, ponieważ znajdują się na niższych poziomach krojenia.
Powiedzmy, że chcemy uzyskać pierwsze pięć wierszy DataFrame
. Jak to się dzieje, że wszystkie trzy z nich działają?
df.loc[:5]
df.ix[:5]
df.iloc[:5]
Czy ktoś może przedstawić trzy przypadki, w których rozróżnienie w zastosowaniu jest wyraźniejsze?
Odpowiedzi:
Uwaga: w pandach w wersji 0.20.0 i nowszych
ix
jest przestarzałe, a zamiast niego zalecane jest używanieloc
iiloc
. Zostawiłem części tej odpowiedzi, które opisująix
nietknięte jako odniesienie dla użytkowników wcześniejszych wersji pand. Dodano przykłady pokazujące alternatywy dlaix
.Po pierwsze, oto podsumowanie trzech metod:
loc
pobiera wiersze (lub kolumny) z konkretnymi etykietami z indeksu.iloc
pobiera wiersze (lub kolumny) w określonych pozycjach w indeksie (więc przyjmuje tylko liczby całkowite).ix
zwykle stara się zachowywać jak,loc
ale wraca do zachowania, jakbyiloc
etykieta nie była obecna w indeksie.Ważne jest, aby zwrócić uwagę na niektóre subtelności, które mogą utrudnić
ix
użycie:jeśli indeks jest liczbą całkowitą,
ix
użyje tylko indeksowania opartego na etykietach, a nie powróci do indeksowania opartego na pozycji. Jeśli etykiety nie ma w indeksie, pojawia się błąd.jeśli indeks nie zawiera tylko liczb całkowitych, to podana liczba całkowita
ix
natychmiast zastosuje indeksowanie oparte na pozycji, a nie indeksowanie oparte na etykietach. Jeśli jednakix
zostanie podany inny typ (np. Ciąg znaków), można zastosować indeksowanie oparte na etykietach.Aby zilustrować różnice między trzema metodami, rozważ następującą serię:
Przyjrzymy się krojeniu na wartość całkowitą
3
.W tym przypadku
s.iloc[:3]
zwraca nam pierwsze 3 wiersze (ponieważ traktuje 3 jako pozycję) is.loc[:3]
zwraca pierwsze 8 wierszy (ponieważ traktuje 3 jako etykietę):Zawiadomienie
s.ix[:3]
zwraca tę samą serię,s.loc[:3]
ponieważ najpierw szuka etykiety, a nie pracy nad pozycją (a indekss
jest typu całkowitego).Co jeśli spróbujemy z etykietą całkowitą, której nie ma w indeksie (powiedzmy
6
)?Tu
s.iloc[:6]
zwraca pierwsze 6 rzędów z serii, jak oczekiwano. Jednaks.loc[:6]
podnosi KeyError, ponieważ6
nie ma go w indeksie.Zgodnie z subtelnościami wspomnianymi powyżej,
s.ix[:6]
teraz podnosi KeyError, ponieważ próbuje działać jak,loc
ale nie może znaleźć6
w indeksie. Ponieważ nasz indeks jest liczbą całkowitąix
, nie zachowuje się podobnieiloc
.Gdyby jednak nasz indeks był typu mieszanego, podana liczba całkowita
ix
zachowałaby się jakiloc
natychmiast zamiast wywoływania KeyError:Należy pamiętać, że
ix
nadal można akceptować liczby całkowite i zachowywać się takloc
:Jako ogólna rada, jeśli indeksujesz tylko za pomocą etykiet lub indeksujesz tylko za pomocą liczb całkowitych, trzymaj się
loc
lubiloc
unikaj nieoczekiwanych wyników - spróbuj nie używaćix
.Łączenie indeksowania opartego na pozycji i na podstawie etykiet
Czasami biorąc pod uwagę DataFrame, będziesz chciał mieszać metody indeksowania etykiet i pozycji dla wierszy i kolumn.
Weźmy na przykład następujące DataFrame. Jak najlepiej pociąć wiersze do „c” włącznie i wziąć pierwsze cztery kolumny?
We wcześniejszych wersjach pand (wcześniejszych niż 0.20.0)
ix
pozwala to zrobić dość starannie - możemy pokroić wiersze według etykiety, a kolumny według pozycji (zwróć uwagę, że w przypadku kolumn,ix
domyślnie będzie to oparte na pozycjonowaniu, ponieważ4
nie jest to nazwa kolumny ):W późniejszych wersjach pand możemy osiągnąć ten wynik za pomocą
iloc
i za pomocą innej metody:get_loc()
to metoda indeksu oznaczająca „uzyskaj pozycję etykiety w tym indeksie”. Zauważ, że od krojenia za pomocąiloc
obejmuje punktu końcowego, musimy dodać 1 do tej wartości, jeśli chcemy również wiersz „c”.Istnieją dalsze przykłady w dokumentacji pand tutaj .
źródło
loc
,iloc
iix
nadal może wywołać ostrzeżenie, jeżeli są one połączone w łańcuch. Użycie przykładowego elementu DataFrame w połączonych dokumentachdfmi.loc[:, 'one'].loc[:, 'second']
powoduje wyświetlenie ostrzeżenia, tak jakdfmi['one']['second']
w przypadku pierwszej operacji indeksowania może zostać zwrócona kopia danych (a nie widok).df.ix[date, 'Cash']
?loc
lubix
powinny działać w takim przypadku. Na przykładdf.loc['2016-04-29', 'Cash']
zwróci wszystkie indeksy wierszy z tą konkretną datą z kolumny „Gotówka”. (Możesz być tak'2016-01'
dokładny, jak chcesz podczas pobierania indeksów z ciągami, np. Wybierze wszystkie czasy danych przypadające w styczniu 2016 r., `` 2016-01-02 11 '' wybierze czasy danych 2 stycznia 2016 r. Z czasem 11: ??: ?? .)iloc
działa w oparciu o pozycjonowanie liczb całkowitych. Niezależnie od tego, jakie są etykiety wierszy, zawsze możesz np. Uzyskać pierwszy wiersz, wykonując tę czynnośćlub ostatnie pięć wierszy wykonując
Możesz także użyć go na kolumnach. Spowoduje to pobranie trzeciej kolumny:
Możesz je połączyć, aby uzyskać przecięcia wierszy i kolumn:
Z drugiej strony
.loc
użyj nazwanych indeksów. Ustawmy ramkę danych z ciągami znaków jako etykietami wierszy i kolumn:Wtedy możemy uzyskać pierwszy wiersz
a drugie dwa rzędy
'date'
kolumny wgi tak dalej. Warto chyba zaznaczyć, że domyślnymi indeksami wierszy i kolumn dla a
DataFrame
są liczby całkowite od 0, w tym przypadkuiloc
iloc
działałyby w ten sam sposób. Właśnie dlatego twoje trzy przykłady są równoważne. Jeśli miałbyś indeks nieliczbowy, taki jak ciągi znaków lub czasy danych,df.loc[:5]
spowodowałby błąd.Możesz także pobierać kolumny tylko za pomocą ramki danych
__getitem__
:Załóżmy teraz, że chcesz mieszać pozycję i indeksowanie nazwane, czyli indeksowanie przy użyciu nazw w wierszach i pozycji w kolumnach (aby to wyjaśnić, mam na myśli wybranie z naszej ramki danych, zamiast tworzenia ramki danych z ciągami znaków w indeksie wierszy i liczbami całkowitymi w indeks kolumny). Oto gdzie
.ix
przychodzi:Myślę, że warto również wspomnieć, że do
loc
metody można również przekazywać wektory boolowskie . Na przykład:Zwróci pierwszy i trzeci rząd
df
. Jest to równoważne zdf[b]
wyborem, ale może być również użyte do przypisania za pomocą wektorów boolowskich:źródło
df.loc[:, :]
. Można go użyć do ponownego przypisania wartości całościDataFrame
lub utworzenia jej widoku.Moim zdaniem zaakceptowana odpowiedź jest myląca, ponieważ używa DataFrame tylko z brakującymi wartościami. Nie podoba mi się również określenie oparte na pozycji
.iloc
i zamiast tego wolę lokalizację całkowitą, ponieważ jest ona bardziej opisowa i dokładnie to, co.iloc
oznacza. Kluczowym słowem jest INTEGER -.iloc
wymaga INTEGERS.Zobacz moją bardzo szczegółową serię blogów na temat wyboru podzbiorów, aby uzyskać więcej
.ix jest przestarzałe i niejednoznaczne i nigdy nie należy go używać
Ponieważ
.ix
jest przestarzałe, skupimy się tylko na różnicach między.loc
i.iloc
.Zanim omówimy różnice, ważne jest, aby zrozumieć, że DataFrames mają etykiety, które pomagają zidentyfikować każdą kolumnę i każdy indeks. Rzućmy okiem na przykładową ramkę DataFrame:
Wszystkie pogrubione słowa są etykietami. Etykiety,
age
,color
,food
,height
,score
istate
są wykorzystywane do kolumn . Pozostałe etykiety,Jane
,Nick
,Aaron
,Penelope
,Dean
,Christina
,Cornelia
służą do indeksu .Podstawowymi sposobami wyboru poszczególnych wierszy w ramce danych są narzędzia indeksujące
.loc
i.iloc
. Każdy z tych indeksatorów może być również używany do jednoczesnego wybierania kolumn, ale na razie łatwiej jest skupić się na wierszach. Ponadto każdy z indeksatorów używa zestawu nawiasów, które bezpośrednio po nazwie dokonują wyboru..loc wybiera dane tylko według etykiet
Najpierw porozmawiamy o
.loc
indeksatorze, który wybiera dane tylko według etykiet indeksu lub kolumn. W naszym przykładowym DataFrame podaliśmy znaczące nazwy jako wartości dla indeksu. Wiele DataFrames nie będzie miało żadnych znaczących nazw i zamiast tego będzie domyślnie tylko liczbami całkowitymi od 0 do n-1, gdzie n jest długością DataFrame.Istnieją trzy różne dane wejściowe, których możesz użyć
.loc
Wybór pojedynczego wiersza z .loc z ciągiem znaków
Aby wybrać pojedynczy wiersz danych, umieść etykietę indeksu wewnątrz następujących nawiasów
.loc
.Zwraca to wiersz danych jako Serię
Zaznaczanie wielu wierszy za pomocą .loc z listą ciągów
Zwraca DataFrame z wierszami w kolejności określonej na liście:
Zaznaczanie wielu wierszy za pomocą .loc z zapisem wycinka
Notacja wycinka jest zdefiniowana przez wartości początkową, zatrzymaną i krokową. Podczas krojenia według etykiety pandy uwzględniają wartość stop na zwrocie. Następujące plastry od Aarona do Deana włącznie. Wielkość kroku nie jest wyraźnie zdefiniowana, ale domyślnie wynosi 1.
Złożone plastry można pobierać w taki sam sposób, jak listy w języku Python.
.iloc wybiera dane tylko według lokalizacji całkowitej
Przejdźmy teraz do
.iloc
. Każdy wiersz i kolumna danych w DataFrame ma liczbę całkowitą, która ją definiuje. Jest to dodatek do etykiety wyświetlanej na wydruku . Lokalizacją całkowitą jest po prostu liczba wierszy / kolumn od góry / po lewej, zaczynająca się od 0.Istnieją trzy różne dane wejściowe, których możesz użyć
.iloc
Wybór pojedynczego wiersza z .iloc z liczbą całkowitą
Zwraca piąty wiersz (liczba całkowita 4) jako szereg
Zaznaczanie wielu wierszy za pomocą .iloc z listą liczb całkowitych
Zwraca DataFrame trzeciego i drugiego do ostatniego wiersza:
Zaznaczanie wielu wierszy za pomocą .iloc z zapisem plastra
Jednoczesny wybór wierszy i kolumn za pomocą .loc i .iloc
Jedną z doskonałych zdolności obu
.loc/.iloc
jest możliwość jednoczesnego wyboru zarówno wierszy, jak i kolumn. W powyższych przykładach wszystkie kolumny zostały zwrócone z każdego wyboru. Możemy wybrać kolumny z tymi samymi typami danych wejściowych, co w przypadku wierszy. Po prostu musimy oddzielić zaznaczenie wiersza i kolumny przecinkiem .Na przykład możemy wybrać wiersze Jane i Dean za pomocą wysokości kolumn, wyniku i stanu w następujący sposób:
Używa to listy etykiet dla wierszy i notacji plastra dla kolumn
Możemy naturalnie wykonywać podobne operacje,
.iloc
używając tylko liczb całkowitych.Jednoczesny wybór z etykietami i lokalizacją całkowitą
.ix
był używany do dokonywania wyborów jednocześnie z etykietami i lokalizacją liczb całkowitych, co było użyteczne, ale czasami mylące i dwuznaczne, i na szczęście zostało wycofane. W przypadku, gdy musisz dokonać wyboru za pomocą kombinacji etykiet i lokalizacji liczb całkowitych, musisz dokonać zarówno etykiet wyboru, jak i lokalizacji liczb całkowitych.Na przykład, jeśli chcemy wybrać wiersze
Nick
iCornelia
wraz z kolumnami 2 i 4, moglibyśmy skorzystać.loc
z konwersji liczb całkowitych na etykiety z następującymi:Lub alternatywnie przekonwertuj etykiety indeksu na liczby całkowite za pomocą
get_loc
metody index.Wybór boolowski
Indeksator .loc może także dokonywać wyboru wartości logicznej. Na przykład, jeśli chcemy znaleźć wszystkie wiersze, w których wiek jest wyższy niż 30 i zwrócić tylko kolumny
food
iscore
, możemy wykonać następujące czynności:Możesz to powtórzyć,
.iloc
ale nie możesz przekazać mu serii boolowskiej. Musisz przekonwertować wartość logiczną na tablicę liczb liczbowych, taką jak ta:Zaznaczanie wszystkich wierszy
Można użyć
.loc/.iloc
tylko do wyboru kolumny. Możesz zaznaczyć wszystkie wiersze za pomocą dwukropka takiego jak ten:Operator indeksowania
[]
może również wybierać wiersze i kolumny, ale nie jednocześnie.Większość ludzi zna podstawowy cel operatora indeksowania DataFrame, którym jest wybieranie kolumn. Ciąg wybiera pojedynczą kolumnę jako Serię, a lista ciągów wybiera wiele kolumn jako ramkę danych.
Korzystanie z listy wybiera wiele kolumn
Ludzie mniej znają to, że przy stosowaniu notacji plastra wybór odbywa się na podstawie etykiet wierszy lub według lokalizacji liczb całkowitych. Jest to bardzo mylące i coś, czego prawie nigdy nie używam, ale działa.
Jednoznaczność z
.loc/.iloc
wysoce korzystne dla wierszy zaznaczania. Sam operator indeksowania nie jest w stanie jednocześnie zaznaczyć wierszy i kolumn.źródło