web-dev-qa-db-ja.com

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

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

  • 最も一般的なオプション.locの代わりに.ilocまたは.ixを使用する必要があるのはなぜですか?
  • .locilocat、およびiatは、.ixが提供できないある程度の正確さを保証する可能性があることを理解していますが、.ixが全面的に最速の解決策となる傾向があるところも読みました。
  • .ix以外のものを利用することの背後にある現実世界のベストプラクティスの推論について説明してください。
146
user4613042

loc:はインデックスに対してのみ機能します。
iloc:役職
ix:インデックスに含まれていなくてもデータフレームからデータを取得できます。
at:スカラー値を取得します。とても速い場所です
iat:スカラー値を取得します。とても早いです

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

注:pandas 0.20.0以降、.ixインデクサーは 廃止予定 になり、より厳密な.ilocおよび.locインデクサーが優先されます。

118
lautremont

pandasが非推奨になったことを考えると、ix0.20用に更新されました。これは、locilocatiatset_valueの使い方だけでなく、位置とラベルを組み合わせたインデックスの作成方法も示しています。


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

特別な注意:スカラーインデクサーが渡されると、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_valuetakable=True - 位置ベース
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)
73
piRSquared

パンダがDataFrameから選択する2つの主な方法があります。

  • Byラベル
  • By整数位置

資料では、整数位置を参照するために用語位置を使用します。私はそれが紛らわしいと感じるので私はこの専門用語が好きではありません。整数位置はより説明的で、正確には.ilocが表すものです。ここでのキーワードはINTEGERです - 整数位置で選択するときは整数を使わなければなりません。

要約を表示する前に、すべて確認しましょう。

.ixは廃止予定であいまいなため、絶対に使用しないでください。

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

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

.at.iatは、機能が追加されていないため、パフォーマンスが少し向上するだけです。あなたが非常に時間に敏感なアプリケーションを持っていない限り、私は彼らの使用を勧めないでしょう。とにかく、私たちは彼らの要約を持っています:

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

ラベルと整数位置による選択に加えて、boolean indexingとしても知られるboolean selectionが存在します。


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

enter image description here

太字内の単語はすべてラベルです。ラベルagename__、colorname__、foodname__、heightname__、scorename__、およびstatename__は、に使用されます。他のラベルJanename__、Nickname__、Aaronname__、Penelopename__、Deanname__、Christinaname__、Cornelianame__は、行のラベルとして使用されます。まとめて、これらの行ラベルはインデックスとして知られています。


DataFrame内の特定の行を選択する主な方法は、.locおよび.ilocインデクサを使用することです。これらの各インデクサーを使用して列を同時に選択することもできますが、ここでは単に行に集中する方が簡単です。また、各インデクサーは、選択するために名前のすぐ後に続く一連の大括弧を使用します。

.locはラベルのみでデータを選択します

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

.locに使用できる3つの異なる入力があります

  • 文字列
  • 文字列のリスト
  • 開始値と終了値として文字列を使用したスライス表記

文字列付きの.locで単一行を選択する

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

df.loc['Penelope']

これはデータ行をSeriesとして返します。

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

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

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

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

enter image description here

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

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

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

enter image description here

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

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

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

.ilocに使用できる3つの異なる入力があります

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

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

df.iloc[4]

これは5行目(整数位置4)をSeriesとして返します。

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を返します。

enter image description here

スライス表記を使用して.ilocで複数行を選択する

df.iloc[:5:3]

enter image description here


.locと.ilocを使用した行と列の同時選択

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

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

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

enter image description here

これは行にラベルのリストを使い、列にスライス表記を使う

整数だけを使用して、.ilocで同様の操作を自然に行うことができます。

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

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

.ixはラベルと整数位置で同時に選択をするために使用されましたが、それは便利ですが混乱を招き、時々あいまいになりました。ラベルと整数位置を組み合わせて選択する必要がある場合は、両方のラベルと整数位置を選択する必要があります。

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

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

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

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

ブール選択

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

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

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

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

すべての行を選択

列選択だけに.loc/.ilocを使用することは可能です。このようにコロンを使用してすべての行を選択できます。

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

enter image description here


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

ほとんどの人はDataFrameインデックス演算子の主な目的、つまり列の選択に精通しています。文字列は単一の列をSeriesとして選択し、文字列のリストは複数の列をDataFrameとして選択します。

df['food']

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

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

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

enter image description here

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

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

enter image description here

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

enter image description here

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

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

.at.iatによる選択

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

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

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

df.iat[2, 5]
'FL'
44
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

この小さな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を使用すると単一のスカラーのみで管理できます。

:-)

4
Fabio Pomi