パンダloc対iloc対ix対at対iat?


171

最近、私の安全な場所(R)からPythonに分岐し始め、でのセルのローカライズ/選択に少し混乱していPandasます。ドキュメントを読みましたが、さまざまなローカリゼーション/選択オプションの実際的な影響を理解するのに苦労しています。

  • 私が今まで使用しなければならない理由がある.locか、.iloc最も一般的なオプションの上には.ix
  • 私はそれを理解し.locilocat、およびiatいくつかの保証正確提供することができ.ix提供することはできませんが、しかし、どこにも読んで.ixボード全体で最速の解決策になる傾向があります。
  • 以外の何かを利用することの背後にある実際のベストプラクティスの推論について説明してください.ix


3
locはラベルベースのインデックスなので、基本的には行の値ilocを検索します。整数の行ベースのインデックスixは、最初にラベルベースを実行する一般的な方法です。失敗すると、整数ベースになります。atは非推奨であり、今後は使用しないことをお勧めします。:考慮すべき他の事は、ドキュメントはかなりはっきりしているあなたは正直に言うと、列の割り当てこれらの方法のうちのいくつかは、スライスを許すとやろうとしている、としているものであるpandas.pydata.org/pandas-docs/stable/indexing.html
EdChum

1
@EdChum-それatが非推奨であるとあなたが言う理由は何ですか?at(またはiat)のドキュメントには表示されません。
Russ

1
それは非推奨ではないエラーです。非推奨にするという話があったと思いますが、このアイデアはより速いと思うので削除されました
EdChum

4
詳細な説明の間locixそしてilocここに:stackoverflow.com/questions/31593201/...
アレックス・ライリー

回答:


142

loc:インデックスのみで動作します
。iloc:位置
ixで動作します。データフレームからデータを取得できます。インデックスに
はありません。スカラー値を取得します。それは非常に高速LOCです
:IATスカラー値を取得します。非常に速いilocです

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

注:の通りpandas 0.20.0.ixインデクサがされて廃止予定より厳密に賛成.ilocし、.locインデクサー。


9
もしatiat非常に高速のバージョンですlociloc、なぜ使用locしてiloc、すべての?
Ray

57
atそしてiat、データフレーム内の単一の要素であるスカラにアクセスしながらすることを意味locし、ilocベクトル化操作を実行するために、潜在的に、同時にアクセスいくつかの要素にメンツです。
ncasas

@ncasas-ドキュメントを読むと、.atはインデックスでのみアクセスできますが、.locは列名でもアクセスできます。より高速な.atを使用する方法はありますが、インデックスの代わりに列名を使用しますか?x = df.loc [df.Id == source_Id、 'someValue']。values [0]をx = df.at [df.Id == source_Id、 'someValue']で置き換えるのと同様です。.atがスローされたバージョンは、「ValueError:整数インデックスに基づくインデックス付けは整数インデクサーのみを持つことができます」
Vega

94

非推奨であるpandas 0.20ことを考慮して更新ixされました。これは、だけでなく、使用する方法を示しlocilocatiatset_value、しかし、混合位置/ラベルベースのインデックスを達成する方法。


loc- ラベルベース
1次元配列をインデクサーとして渡すことができます。配列は、インデックスまたは列のスライス(サブセット)にすることも、インデックスまたは列と同じ長さのブール配列にすることもできます。

特記事項:スカラーインデクサーが渡されると、loc以前には存在しなかった新しいインデックスまたは列の値を割り当てることができます。

# 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- 位置ベースインデックス値ではなく位置
loc除いてと同様です。ただし、新しい列またはインデックスを割り当てることはできません

# 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- スカラーインデクサー と非常によく似たラベルベースの
作品loc。 配列インデクサーを操作できませんできる!新しいインデックスと列を割り当てます。

利点を超えるがloc、これが高速であるということです。
欠点は、インデクサーに配列を使用できないことです。

# 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- 位置に基づく
と同様に機能しilocます。 配列インデクサーで機能しませんできません!新しいインデックスと列を割り当てます。

利点を超えるがiloc、これが高速であるということです。
欠点は、インデクサーに配列を使用できないことです。

# 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- スカラーインデクサー と非常によく似たラベルベースの
作品loc。 配列インデクサーを操作できませんできる!新しいインデックスと列を割り当てる

利点オーバーヘッドが非常に少ないため、超高速です。
短所pandas一連の安全性チェックを行わないため、オーバーヘッドはほとんどありません。 自己責任で使用してください。また、これは一般利用を目的としたものではありません。

# 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_valuewithtakable=True - position based
と同様に機能しilocます。 配列インデクサーで機能しませんできません!新しいインデックスと列を割り当てます。

利点オーバーヘッドが非常に少ないため、超高速です。
短所pandas一連の安全性チェックを行わないため、オーバーヘッドはほとんどありません。 自己責任で使用してください。また、これは一般利用を目的としたものではありません。

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

では、複数の列を位置で読み取り/設定する簡単な方法はありますか?さらに、たとえば、値の配列をそれぞれ新しい列に追加したかったのですが、これは簡単にできますか?
wordsmith

@wordsmithデータフレームの最後に新しい列を追加する簡単な方法があります。または始まりですら。ポジションが関与している場合は、いいえ、簡単な方法はありません。
piRSquared 2017年

この答えは私が必要としていたものでした!パンダは確かに強力ですが、それはすべてを理解してつなぎ合わせるのが非常に複雑になるという犠牲を伴います。
slhck 2018

1
注記set_valueの賛成で廃止されました.atし、.iat以来、バージョン0.21
nedned

59

パンダがDataFrameから選択を行う主な方法は2つあります。

  • ラベル
  • 整数の場所

ドキュメントでは、整数の位置を指すために位置という用語を使用しています。わかりにくいので、この用語は好きではありません。整数の場所はより説明的であり、まさにその.iloc意味です。ここでのキーワードはINTEGERです。整数の場所で選択する場合は整数を使用する必要があります。

概要を表示する前に、すべてのことを確認しましょう...

.ixは非推奨であり、あいまいであるため、使用しないでください。

パンダには3つの主要なインデクサーがあります。インデックス演算子自体(角かっこ[])、、.locおよびがあり.ilocます。それらを要約しましょう:

  • []-主に列のサブセットを選択しますが、行も選択できます。行と列を同時に選択することはできません。
  • .loc -ラベルのみで行と列のサブセットを選択します
  • .iloc -整数位置のみで行と列のサブセットを選択します

私はほとんど使用し.atたり.iat、追加機能を追加したりせず、わずかなパフォーマンスの向上で使用しています。非常に時間に敏感なアプリケーションがない限り、それらの使用はお勧めしません。とにかく、それらの要約があります:

  • .at ラベルのみでDataFrameの単一のスカラー値を選択します
  • .iat 整数の位置のみでDataFrameの単一のスカラー値を選択します

ラベルと整数の場所による選択に加えて、ブールインデックスとも呼ばれるブール選択が存在します。


説明例として.loc.ilocブール選択と.atし、.iat以下に示します

私たちは、最初の間の違いに焦点を当てる.loc.iloc。違いについて説明する前に、DataFrameには各列と各行を識別するのに役立つラベルがあることを理解することが重要です。サンプルDataFrameを見てみましょう:

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

ここに画像の説明を入力してください

太字の単語はすべてラベルです。ラベルは、agecolorfoodheightscoreおよびstateのために使用されている。他のラベルは、JaneNickAaronPenelopeDeanChristinaCornelia行のラベルとして使用されています。これらの行ラベルをまとめて、インデックスと呼びます


DataFrameの特定の行を選択する主な方法は、.locおよび.ilocインデクサーを使用することです。これらの各インデクサーを使用して列を同時に選択することもできますが、今のところは、行に焦点を合わせる方が簡単です。また、各インデクサーは、名前の直後に続くブラケットのセットを使用して選択を行います。

.locはラベルによってのみデータを選択します

最初に.loc、インデックスまたは列ラベルによってのみデータを選択するインデクサーについて説明します。サンプルのDataFrameでは、インデックスの値として意味のある名前を提供しています。多くのDataFrameには意味のある名前がなく、代わりにデフォルトで0からn-1までの整数に設定されます。nはDataFrameの長さ(行数)です。

あなたがそれらのうちの3つに 使用できる多くの異なる入力があります.loc

  • 文字列
  • 文字列のリスト
  • 文字列を開始値および終了値として使用するスライス表記

文字列を含む.locで単一の行を選択する

1行のデータを選択するには、インデックスラベルを角かっこ内に配置します.loc

df.loc['Penelope']

データの行をシリーズとして返します

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

文字列のリストを含む.locで複数の行を選択する

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

これは、リストで指定された順序で行を持つDataFrameを返します。

ここに画像の説明を入力してください

スライス表記の.locで複数の行を選択する

スライス表記は、開始、停止、およびステップの値で定義されます。ラベルでスライスすると、パンダは戻り値にストップ値を含めます。以下のアーロンからディーンまでのスライス。そのステップサイズは明示的に定義されていませんが、デフォルトは1です。

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

ここに画像の説明を入力してください

複雑なスライスは、Pythonリストと同じ方法で取得できます。

.ilocは整数位置のみでデータを選択します

次にに移りましょう.iloc。DataFrameのデータのすべての行と列には、それを定義する整数の場所があります。これは、出力に視覚的に表示されるラベルに追加されます。整数の位置は、0から始まる上/左からの行/列の数です。

あなたがそれらのうちの3つに 使用できる多くの異なる入力があります.iloc

  • 整数
  • 整数のリスト
  • 開始値と終了値として整数を使用するスライス表記

整数を含む.ilocで単一の行を選択する

df.iloc[4]

これは、5行目(整数位置4)をシリーズとして返します

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

整数のリストを含む.ilocで複数の行を選択する

df.iloc[[2, -2]]

これは、3番目と2番目から最後の行のDataFrameを返します。

ここに画像の説明を入力してください

スライス表記の.ilocで複数の行を選択する

df.iloc[:5:3]

ここに画像の説明を入力してください


.locおよび.ilocによる行と列の同時選択

両方の優れた機能の1つ.loc/.ilocは、行と列の両方を同時に選択できることです。上記の例では、すべての列が各選択から返されました。行と同じタイプの入力を持つ列を選択できます。行と列の選択をカンマで区切るだけです。

たとえば、行JaneとDeanを次のように列の高さ、スコア、状態だけで選択できます。

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

ここに画像の説明を入力してください

これは、行のラベルのリストと列のスライス表記を使用します

自然に.iloc整数のみを使用して同様の操作を実行できます。

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

ラベルと整数位置による同時選択

.ixは、ラベルと整数の位置と同時に選択を行うために使用されましたが、これは有用でしたが、時折混乱し、あいまいであり、ありがたいことに、廃止されました。ラベルと整数の場所を組み合わせて選択する必要がある場合は、選択ラベルまたは整数の場所の両方を選択する必要があります。

たとえば、行NickCornelia列2および4 を選択する場合は.loc、次のように整数をラベルに変換して使用できます。

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

または、get_locindexメソッドを使用して、インデックスラベルを整数に変換します。

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

ブール選択

.locインデクサーはブール選択も実行できます。たとえば、年齢が30を超えるすべての行を検索して、foodおよびscore列のみを返す場合、次のようにできます。

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

これを複製することはでき.ilocますが、ブールシリーズを渡すことはできません。次のように、ブールSeriesをnumpy配列に変換する必要があります。

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

すべての行を選択する

.loc/.iloc列の選択だけに使用できます。次のようにコロンを使用して、すべての行を選択できます。

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

ここに画像の説明を入力してください


インデックス付け演算子は[]、行と列を同時に選択することはできませんがスライスできます。

ほとんどの人は、列を選択することであるDataFrameインデックス演算子の主な目的に精通しています。文字列は1つの列をシリーズとして選択し、文字列のリストは複数の列をデータフレームとして選択します。

df['food']

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

リストを使用して複数の列を選択する

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

ここに画像の説明を入力してください

あまり知られていないのは、スライス表記が使用される場合、選択は行ラベルまたは整数の場所によって行われることです。これは非常にわかりにくく、ほとんど使用しませんが、機能します。

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

ここに画像の説明を入力してください

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

ここに画像の説明を入力してください

.loc/.iloc行を選択するためのの明示性は非常に優先されます。インデックス付け演算子だけでは、行と列を同時に選択することはできません。

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

選択.at.iat

による選択は.atとほぼ同じです.locが、DataFrame内の単一の「セル」のみを選択します。通常、このセルをスカラー値と呼びます。を使用する.atには、行と列の両方のラベルをカンマで区切って渡します。

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

での選択は.iatとほぼ同じです.ilocが、単一のスカラー値のみを選択します。行と列の両方の位置に整数を渡す必要があります

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

この小さな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))

私たちはそうするでしょう

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

これにより、次のようになります。

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

したがって、サブセットに.iatを使用することはできません。.ilocのみを使用する必要があります。

しかし、両方の大きなdfから選択して、速度を確認してみましょう...

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

したがって、.locではサブセットを管理でき、.atでは単一のスカラーしか使用できませんが、.atは.locより高速です。

:-)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.