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


171

Son zamanlarda güvenli yerimden (R) Python'a dallanmaya başladı ve içindeki hücre lokalizasyonu / seçimi ile biraz kafam karıştı Pandas. Belgeleri okudum ancak çeşitli yerelleştirme / seçim seçeneklerinin pratik sonuçlarını anlamak için uğraşıyorum.

  • Şimdiye kadar kullanması gereken bir neden var mı .locyoksa .ilocen genel seçeneği üzerinde .ix?
  • Anlıyorum .loc, iloc, atve iatbazı garantili doğruluğunu sağlayabilir .ixsunamıyoruz, ama nerede ben de okudum .ixyönüyle en hızlı çözüm olma eğilimindedir.
  • Başka bir şey kullanan arkasında akıl yürütme gerçek dünya, en iyi uygulamaları açıklayınız .ix?


3
locetiket tabanlı indeksleme temelde bir satırdaki bir değeri aramak iloc, tamsayı satır tabanlı indeksleme, ixilk önce etiket tabanlı bir genel yöntemdir, eğer başarısız olursa tamsayı tabanlı olur. atkullanımdan kaldırılmıştır ve artık bunu kullanmamanız önerilir. Dikkate alınması gereken diğer bir şey, bu yöntemlerden bazıları dilimlemeye ve sütun atamaya izin verdiğinden, belgelerin oldukça açık olduğu için yapmaya
çalıştığınız şeydir

1
@EdChum - bunun atkullanımdan kaldırıldığını söyleyen nedir? Bunu at (veya iat ) belgelerinde görmüyorum .
Russ

1
Bu, kullanımdan kaldırılmayan bir hata, sanırım onu ​​reddetme hakkında bir konuşma vardı, ancak bu fikir düştü çünkü daha hızlı olduğunu düşünüyorum
EdChum

4
Detay açıklama arasındaki loc, ixve ilocburada: stackoverflow.com/questions/31593201/...
Alex Riley

Yanıtlar:


142

loc: yalnızca index üzerinde çalışır
iloc: position
ix üzerinde çalışır : Veri çerçevesinden verileri şu dizinde olmadan alabilirsiniz
: skaler değerler olsun. Çok hızlı bir yer belirleme
: Skaler değerleri alın. Çok hızlı bir iloc

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

Not: itibarıyla pandas 0.20.0, .ixindeksleyicinin edilir kaldırılmış daha sıkı lehine .ilocve .locDizinleyicilere.


9
Eğer atve iatçok hızlı versiyonları vardır locve iloco zaman neden kullanımı locve iloctüm?
Ray

58
atve iatsırasında, bir skaler, dataframe tek bir öğeyi ulaşmak için anlamına locve ilocaynı zamanda erişim çeşitli elemanlara ments potansiyel olarak vektörlü işlemleri gerçekleştirmek için.
ncasas

@ncasas - Belgeleri doğru okursam .at sadece dizin tarafından erişebilirken .loc sütun adına göre de erişebilir. Daha hızlı .at kullanmanın bir dizin yerine sütun adını kullanmanın bir yolu var mı? X = df.loc [df.Id == source_Id, 'someValue']. ​​[0] değerlerini x = df.at [df.Id == source_Id, 'someValue'] ile değiştirmek gibi. .At ile sürüm atar "ValueError: Bir tamsayı endeksine dayalı indeksleme sadece tamsayı indeksleyicileri olabilir"
Vega

94

İçin güncellenmiş pandas 0.20verilen ixkullanımdan kaldırıldı. Bu sadece nasıl kullanılacağını göstermektedir loc, iloc, at, iat, set_value, ama, karışık pozisyonel / etiket bazlı endeksleme gerçekleştirmek için nasıl.


loc- label based
1-B dizileri dizin oluşturucu olarak geçirmenizi sağlar. Diziler, dizinin veya sütunun dilimleri (alt kümeleri) olabilir veya dizine veya sütunlara eşit uzunluktaki boole dizileri olabilir.

Özel Not: bir skaler indeksleyici geçtiğinde, locdaha önce mevcut olmayan yeni bir indeks veya sütun değeri atayabilir.

# 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- pozisyon bazlı
benzer locziyade pozisyonlarda o endeks değerleriyle hariç. Ancak, olamaz yeni sütunlar veya endekslerini atayın.

# 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- etiket tabanlı Skaler indeksleyicilere
çok benzer loc. Can not dizi Dizinleyicilere üzerinde çalışırlar. Yapabilmek! yeni dizinler ve sütunlar atayın.

Avantajı üzerinde locbu hızlı olmasıdır.
Dezavantajı , dizin oluşturucular için dizileri kullanamamanızdır.

# 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- pozisyon bazlı
benzer Works iloc. Can not dizi Dizinleyicilere çalışmaktadır. Olumsuz! yeni dizinler ve sütunlar atayın.

Avantajı üzerinde ilocbu hızlı olmasıdır.
Dezavantajı , dizin oluşturucular için dizileri kullanamamanızdır.

# 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- etiket tabanlı Skaler indeksleyicilere
çok benzer loc. Can not dizi Dizinleyicilere üzerinde çalışırlar. Yapabilmek! yeni dizinler ve sütunlar atayın

Avantaj Süper hızlı, çünkü çok az ek yük var!
Dezavantaj Çok az ek yük var çünkü pandasbir sürü güvenlik kontrolü yapmıyor. Kendi sorumluluğunuzdadır kullanın . Ayrıca, bu kamusal kullanım için tasarlanmamıştır.

# 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_valueiletakable=True - pozisyon bazlı
benzer Worksiloc. Can not dizi Dizinleyicilere çalışmaktadır. Olumsuz! yeni dizinler ve sütunlar atayın.

Avantaj Süper hızlı, çünkü çok az ek yük var!
Dezavantaj Çok az ek yük var çünkü pandasbir sürü güvenlik kontrolü yapmıyor. Kendi sorumluluğunuzdadır kullanın . Ayrıca, bu kamusal kullanım için tasarlanmamıştır.

# 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)

Peki, birden çok sütunu konuma göre okumak / ayarlamak için basit bir yol var mı? Ayrıca, yeni sütunlara bir dizi değer eklemek istedim, bu kolayca yapılabilir mi?
wordsmith

@wordsmith, veri çerçevesinin sonuna yeni sütunlar eklemenin kolay ish yolları vardır. Hatta başlangıç. Pozisyonlar söz konusu ise hayır, kolay bir yol yoktur.
piRSquared

Bu cevap tam ihtiyacım olan şeydi! Pandalar kesinlikle güçlüdür, ancak bu her şeyi anlamak ve bir araya getirmek için son derece karmaşık hale getirmek pahasına gelir.
slhck

1
Not set_valuelehine itiraz edildi .atve .iatyana sürüm 0.21
nedned

59

Pandaların bir DataFrame'den seçim yapmasının iki ana yolu vardır.

  • by Label
  • By Tamsayı Yer

Belgeler, tamsayı konumuna atıfta bulunmak için konum terimini kullanır . Kafa karıştırıcı olduğunu düşündüğüm için bu terminolojiyi sevmiyorum. Tamsayı konumu daha açıklayıcı ve tam olarak ne anlama geliyor . Buradaki anahtar kelime INTEGER.iloc - tamsayı konumuna göre seçim yaparken tamsayıları kullanmalısınız.

Özeti göstermeden önce şunlardan emin olalım ...

.ix kullanımdan kaldırıldı ve belirsiz ve asla kullanılmamalıdır

Pandalar için üç birincil dizinleyici vardır . Dizin oluşturma operatörünün kendisi (parantezler []) .loc, ve .iloc. Onları özetleyelim:

  • []- Öncelikle sütun alt kümelerini seçer, ancak satırları da seçebilir. Aynı anda satır ve sütun seçilemez.
  • .loc - satırların ve sütunların alt kümelerini yalnızca etikete göre seçer
  • .iloc - satırların ve sütunların alt kümelerini yalnızca tamsayı konumuna göre seçer

Neredeyse hiç kullanmıyorum .atveya .iatek işlevsellik eklemedikleri için ve sadece küçük bir performans artışı ile. Çok zamana duyarlı bir uygulamanız yoksa kullanımlarını caydırırdım. Ne olursa olsun, onların özeti var:

  • .at DataFrame'de yalnızca etikete göre tek bir skaler değer seçer
  • .iat DataFrame'de yalnızca tamsayı konumuna göre tek bir skaler değer seçer

Etikete ve tamsayı konumuna göre seçime ek olarak, boole dizine ekleme olarak da bilinen boole seçimi vardır.


Örnekler açıklama .loc, .ilocboolean seçimi ve .atve .iataşağıda gösterilmiştir

Önce .locve arasındaki farklara odaklanacağız .iloc. Farklılıklar hakkında konuşmadan önce, DataFrame'lerin her sütunu ve her satırı tanımlamaya yardımcı olan etiketlere sahip olduğunu anlamak önemlidir. Örnek bir DataFrame'e bakalım:

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'])

resim açıklamasını buraya girin

Kalın yazılmış tüm kelimeler etiketlerdir. Etiketler, age, color, food, height, scoreve statekullanılan sütunlar . Diğer etiketler, Jane, Nick, Aaron, Penelope, Dean, Christina, Corneliasatırlar için etiket olarak kullanılır. Toplu olarak, bu satır etiketleri dizin olarak bilinir .


Bir DataFrame içinde belirli satırları seçmenin birincil yolları .locve .ilocindeksleyicileridir. Bu dizinleyicilerin her biri aynı anda sütunları seçmek için de kullanılabilir, ancak şimdilik sadece satırlara odaklanmak daha kolaydır. Ayrıca, dizinleyicilerin her biri seçimlerini yapmak için adlarını hemen takip eden bir küme parantez kullanır.

.loc verileri yalnızca etiketlerle seçer

Önce hakkında konuşacağız .loc yalnızca dizin veya sütun etiketlerine göre veri seçen dizinleyici . Örnek DataFrame'imizde, dizin için değer olarak anlamlı adlar verdik. Birçok DataFrames anlamlı bir isme sahip olmayacak ve bunun yerine, sadece 0 ile n-1 arasındaki tamsayıları varsayılan olarak alacaktır; burada n, DataFrame'in uzunluğudur (satır sayısı).

Bunlardan üçü için kullanabileceğiniz birçok farklı giriş.loc vardır.

  • Dizi
  • Dizelerin bir listesi
  • Başlangıç ​​ve bitiş değerleri olarak dizeleri kullanarak dilim gösterimi

Bir dizeyle .loc ile tek bir satır seçme

Tek bir veri satırı seçmek için dizin etiketini aşağıdaki parantezlerin içine yerleştirin .loc.

df.loc['Penelope']

Bu, veri satırını Seri olarak döndürür

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

Dize listesiyle .loc ile birden çok satır seçme

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

Bu, satırları listede belirtilen sırayla içeren bir DataFrame döndürür:

resim açıklamasını buraya girin

Dilim gösterimiyle .loc ile birden çok satır seçme

Dilim gösterimi bir başlangıç, durdurma ve adım değerleri ile tanımlanır. Etikete göre dilimleme yaparken, pandalar dönüşte durma değerini içerir. Aaron'dan Dean'e aşağıdaki dilimler dahil. Adım boyutu açıkça tanımlanmadı, ancak varsayılan olarak 1.

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

resim açıklamasını buraya girin

Karmaşık dilimler, Python listelerinde olduğu gibi alınabilir.

.iloc yalnızca tamsayı konumuna göre veri seçer

Şimdi dönelim .iloc. Bir DataFrame'deki her veri satırı ve sütunu, onu tanımlayan bir tamsayı konumuna sahiptir. Bu, çıktıda görsel olarak görüntülenen etikete ek olarak yapılır. Tamsayı konumu, 0'dan başlayarak üst / soldan başlayan satır / sütun sayısıdır.

Bunlardan üçü için kullanabileceğiniz birçok farklı giriş.iloc vardır.

  • Bir tam sayı
  • Tamsayıların listesi
  • Başlangıç ​​ve bitiş değerleri olarak tamsayılar kullanarak dilim gösterimi

.İloc ile bir tamsayı içeren tek bir satır seçme

df.iloc[4]

Bu, 5. satırı (tamsayı konumu 4) Seri olarak döndürür

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

Tam sayı listesiyle .iloc ile birden çok satır seçme

df.iloc[[2, -2]]

Bu, üçüncü ve ikinci ile son satırların DataFrame'lerini döndürür:

resim açıklamasını buraya girin

Dilim gösterimiyle .iloc ile birden çok satır seçme

df.iloc[:5:3]

resim açıklamasını buraya girin


.Loc ve .iloc ile aynı anda satır ve sütun seçimi

Her ikisinin de mükemmel bir yeteneği, .loc/.ilochem satırları hem de sütunları aynı anda seçebilmeleridir. Yukarıdaki örneklerde, tüm sütunlar tüm seçimlerden döndürülmüştür. Satırlar için yaptığımız girişlerin aynısı olan sütunları seçebiliriz. Yalnızca satır ve sütun seçimini virgülle ayırmamız gerekir .

Örneğin, Jane ve Dean satırlarını yalnızca sütun yüksekliği, puanı ve durumuyla aşağıdaki gibi seçebiliriz:

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

resim açıklamasını buraya girin

Bu, satırlar için bir etiket listesi ve sütunlar için dilim gösterimi kullanır

Doğal olarak .ilocsadece tamsayılar kullanarak benzer işlemler yapabiliriz .

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

Etiketler ve tamsayı konumu ile eşzamanlı seçim

.ixetiketler ve tamsayı konumu ile eşzamanlı olarak seçim yapmak için kullanıldı, bu da zaman zaman kafa karıştırıcı ve belirsizdi ve neyse ki kullanımdan kaldırıldı. Bir etiket ve tamsayı konumu karışımıyla seçim yapmanız gerektiğinde, hem seçim etiketlerinizi hem de tamsayı konumlarını yapmanız gerekir.

Örneğin, satırları Nickve Corneliasütun 2 ve 4 ile birlikte seçmek istiyorsak .loc, tam sayıları etiketlere aşağıdakilerle dönüştürerek kullanabiliriz :

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

Alternatif olarak, dizin etiketlerini get_locdizin yöntemiyle tamsayılara dönüştürün .

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

Boole Seçimi

.Loc dizinleyici de boole seçimini yapabilir. Örneğin, yaşın 30'un üzerinde olduğu tüm satırları bulmak ve yalnızca foodve scoresütunlarını döndürmek istiyorsak aşağıdakileri yapabiliriz:

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

Bunu ile çoğaltabilirsiniz, .ilocancak bir boolean serisi geçiremezsiniz. Boolean Serisini aşağıdaki gibi bir numpy dizisine dönüştürmelisiniz:

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

Tüm satırları seçme

.loc/.ilocSadece sütun seçimi için kullanılabilir . Aşağıdaki gibi iki nokta üst üste kullanarak tüm satırları seçebilirsiniz:

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

resim açıklamasını buraya girin


Dizin oluşturma operatörü,, []dilim satırları ve sütunları da seçebilir, ancak aynı anda seçemez.

Çoğu kişi DataFrame indeksleme operatörünün temel amacına aşinadır, bu da sütunları seçmektir. Bir dize, tek bir sütunu Seri olarak seçer ve dizelerin listesi birden çok sütunu DataFrame olarak seçer.

df['food']

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

Liste kullanmak birden çok sütun seçer

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

resim açıklamasını buraya girin

İnsanların daha az aşina oldukları şey, dilim gösterimi kullanıldığında, seçimin satır etiketleri veya tamsayı konumu ile gerçekleşmesidir. Bu çok kafa karıştırıcı ve neredeyse hiç kullanmadığım bir şey ama işe yarıyor.

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

resim açıklamasını buraya girin

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

resim açıklamasını buraya girin

Bir anlaşılırlık .loc/.ilocseçme satırlar için oldukça tercih edilir. Yalnızca dizin oluşturma operatörü, satırları ve sütunları aynı anda seçemez.

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

Tarafından Seçme .atve.iat

İle seçim .athemen hemen aynıdır, .locancak DataFrame'inizde yalnızca tek bir 'hücre' seçer. Genellikle bu hücreye skaler değer diyoruz. Kullanmak için .at, virgülle ayrılmış bir satır ve sütun etiketi iletin.

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

İle seçim .iatneredeyse aynıdır, .ilocancak yalnızca tek bir skaler değer seçer. Hem satır hem de sütun konumları için bir tam sayı iletmeniz gerekir

df.iat[2, 5]
'FL'

31
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

4

Bu küçük df ile başlayalım:

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))

Bizde olacak

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

Bununla birlikte:

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

Bu nedenle .iat öğesini yalnızca .iloc kullanmamız gereken alt küme için kullanamayız.

Ama ikisini de daha büyük bir df'den seçmeye çalışalım ve hızı kontrol edelim ...

# -*- 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

Bu nedenle .loc ile alt kümeleri yönetebiliriz.

:-)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.