iloc、ix、locの違いは何ですか?


636

誰かがこれらの3つのスライス方法がどのように異なるか説明できますか?
私はドキュメントを見てこれらの 答えを見ました、それでも私は3つがどのように違うのか説明することができません。私にとっては、スライスのレベルが低いため、それらは大部分が交換可能に見えます。

たとえば、の最初の5行を取得するとしDataFrameます。これら3つすべてがどのように機能するのですか?

df.loc[:5]
df.ix[:5]
df.iloc[:5]

誰かが使用の区別がより明確な3つのケースを提示できますか?


7
:SettingWithCopyWarningシナリオに言及することは非常に重要stackoverflow.com/questions/20625582/...stackoverflow.com/questions/23688307/...
ポール・

9
ixは非推奨となる予定です: github.com/pandas-dev/pandas/issues/14218
JohnE

回答:


970

注:パンダのバージョン0.20.0以上では、ixされて非推奨との使用lociloc代わりに奨励されています。ix以前のバージョンのパンダのユーザーのためのリファレンスとしてそのまま説明するこの回答の部分は残しました。の代替を示す例を以下に追加しました ix


まず、3つの方法の要約を次に示します。

  • locインデックスから特定のラベルを持つ行(または列)を取得します。
  • ilocインデックスの特定の位置にある行(または列)を取得します(つまり、整数のみを取ります)。
  • ix通常はのように動作しようとしますlociloc、ラベルがインデックスに存在しない場合のように動作にフォールバックします。

ix使用するのが少し難しいかもしれないいくつかの微妙な点に注意することが重要です:

  • インデックスが整数型の場合、ixラベルベースのインデックスのみを使用し、位置ベースのインデックスにフォールバックしません。ラベルがインデックスにない場合、エラーが発生します。

  • インデックスに整数のみが含まれていない場合、整数を指定するixと、ラベルベースのインデックスではなく、位置ベースのインデックスがすぐに使用されます。ただし、ix別のタイプ(文字列など)が指定されている場合は、ラベルベースのインデックスを使用できます。


3つの方法の違いを説明するために、次のシリーズを検討してください。

>>> s = pd.Series(np.nan, index=[49,48,47,46,45, 1, 2, 3, 4, 5])
>>> s
49   NaN
48   NaN
47   NaN
46   NaN
45   NaN
1    NaN
2    NaN
3    NaN
4    NaN
5    NaN

整数値によるスライスについて見ていきます3

この場合、s.iloc[:3]最初の3行を返し(3を位置として扱うため)s.loc[:3]、最初の8行を返します(3をラベルとして扱うため):

>>> s.iloc[:3] # slice the first three rows
49   NaN
48   NaN
47   NaN

>>> s.loc[:3] # slice up to and including label 3
49   NaN
48   NaN
47   NaN
46   NaN
45   NaN
1    NaN
2    NaN
3    NaN

>>> s.ix[:3] # the integer is in the index so s.ix[:3] works like loc
49   NaN
48   NaN
47   NaN
46   NaN
45   NaN
1    NaN
2    NaN
3    NaN

通知は、s.ix[:3]同じシリーズを返しs.loc[:3]、それはラベルを探しますので、最初のではなく位置での作業(とのインデックスはs、整数型です)。

インデックスにない整数ラベル(たとえば6)を使用するとどうなるでしょうか。

ここではs.iloc[:6]、予想通りシリーズの最初の6行を返します。ただし、s.loc[:6]6インデックスにないため、KeyErrorが発生します。

>>> s.iloc[:6]
49   NaN
48   NaN
47   NaN
46   NaN
45   NaN
1    NaN

>>> s.loc[:6]
KeyError: 6

>>> s.ix[:6]
KeyError: 6

上記のように微妙なように、インデックス内でa が見つからないs.ix[:6]ように機能しようとするため、KeyErrorが発生します。インデックスが整数型であるため、のように動作するようにフォールバックしません。loc6ixiloc

ただし、インデックスが混合型の場合、整数ixを指定するとiloc、KeyErrorが発生する代わりに、すぐに動作します。

>>> s2 = pd.Series(np.nan, index=['a','b','c','d','e', 1, 2, 3, 4, 5])
>>> s2.index.is_mixed() # index is mix of different types
True
>>> s2.ix[:6] # now behaves like iloc given integer
a   NaN
b   NaN
c   NaN
d   NaN
e   NaN
1   NaN

ixは非整数を受け入れ、次のように動作することに注意してくださいloc

>>> s2.ix[:'c'] # behaves like loc given non-integer
a   NaN
b   NaN
c   NaN

あなただけのラベルを使用してインデックスを作成している場合、一般的なアドバイスとして、またはだけで整数位置、スティックを使用してインデックスを作成locまたはiloc使用しないようにしてください-予期しない結果を避けるためにix


位置ベースとラベルベースのインデックスの組み合わせ

DataFrameが指定されている場合は、行と列のラベルと位置のインデックス方法を混在させたいことがあります。

たとえば、次のDataFrameについて考えます。「c」までの行をスライスして、最初の4列取得するのに最適な方法はどれですか。

>>> df = pd.DataFrame(np.nan, 
                      index=list('abcde'),
                      columns=['x','y','z', 8, 9])
>>> df
    x   y   z   8   9
a NaN NaN NaN NaN NaN
b NaN NaN NaN NaN NaN
c NaN NaN NaN NaN NaN
d NaN NaN NaN NaN NaN
e NaN NaN NaN NaN NaN

以前のバージョンのパンダ(0.20.0より前)ixでは、これを非常にきれいに行うことができます-ラベルで行を、位置で列をスライスできます(列の場合、列名ではないため、ixデフォルトでは位置ベースのスライスになり 4ます) ):

>>> df.ix[:'c', :4]
    x   y   z   8
a NaN NaN NaN NaN
b NaN NaN NaN NaN
c NaN NaN NaN NaN

新しいバージョンのパンダではiloc、別の方法を使用してこの結果を得ることができます:

>>> df.iloc[:df.index.get_loc('c') + 1, :4]
    x   y   z   8
a NaN NaN NaN NaN
b NaN NaN NaN NaN
c NaN NaN NaN NaN

get_loc()「このインデックス内のラベルの位置を取得する」ことを意味するインデックスメソッドです。でのスライスilocはそのエンドポイントを除外しているため、行「c」も必要な場合は、この値に1を追加する必要があることに注意してください。

ここのパンダのドキュメントにさらに例があります


12
素晴らしい説明!私がいつも持っていた関連する質問の1つは、loc、iloc、ixがあるとすれば、SettingWithCopy警告とどのような関係があるのですか?そこにいくつかのドキュメントがあるが、私はまだ少し混乱している正直に言うとpandas.pydata.org/pandas-docs/stable/...
measureallthethings

3
@measureallthethings: locilocおよびixそれらが一緒に連鎖されている場合は、まだ警告をトリガすることがあります。リンクされたドキュメントでサンプルのDataFrameを使用すると、最初のインデックス付け操作によって(ビューではなく)データのコピーが返される可能性があるためdfmi.loc[:, 'one'].loc[:, 'second']、警告がトリガーdfmi['one']['second']されます。
Alex Riley

日付などでDateIndexを検索したい場合は何を使用しますdf.ix[date, 'Cash']か?
cjm2671

@ cjm2671:両方locまたはixその場合は動作するはずです。たとえばdf.loc['2016-04-29', 'Cash']、 'Cash'列から特定の日付のすべての行インデックスを返します。(文字列を含むインデックスを取得する場合は、具体的に指定できます。たとえば'2016-01'、2016年1月に該当するすべての日時を選択します。「2016-01-02 11」は、2016年1月2日の日時を11:??:?? 。)
Alex Riley

ある時点でこの回答を更新したい場合のために、ix github.com/pandas-dev/pandas/issues/14218の
JohnE

142

iloc整数ポジショニングに基づいて動作します。したがって、行ラベルが何であっても、いつでも最初の行を取得できます。

df.iloc[0]

または最後の5行

df.iloc[-5:]

カラムにも使用できます。これにより、3番目の列が取得されます。

df.iloc[:, 2]    # the : in the first position indicates all rows

それらを組み合わせて、行と列の交差を取得できます。

df.iloc[:3, :3] # The upper-left 3 X 3 entries (assuming df has 3+ rows and columns)

一方、.loc名前付きインデックスを使用します。行と列のラベルとして文字列を含むデータフレームを設定してみましょう。

df = pd.DataFrame(index=['a', 'b', 'c'], columns=['time', 'date', 'name'])

次に、最初の行を取得できます

df.loc['a']     # equivalent to df.iloc[0]

そして、の第二列'date'の列によって

df.loc['b':, 'date']   # equivalent to df.iloc[1:, 1]

等々。さて、それはおそらく、デフォルトの行と列のインデックスと指摘価値がDataFrame0からこの場合の整数であるilocloc同じように動作します。これが、3つの例が同等である理由です。文字列や日時などの非数値のインデックスがある場合 df.loc[:5] 、エラーが発生します。

また、データフレームを使用するだけで列を取得できます__getitem__

df['time']    # equivalent to df.loc[:, 'time']

ここで、位置と名前付きインデックス付け、つまり行の名前と列の位置を使用したインデックス付けを混合するとします(明確にするために、行インデックスに文字列と整数を含むデータフレームを作成するのではなく、データフレームから選択することを意味します)列インデックス)。これはどこに.ix来るかです:

df.ix[:2, 'time']    # the first two rows of the 'time' column

また、ブールベクトルをlocメソッドに渡すことができることも言及する価値があると思います。例えば:

 b = [True, False, True]
 df.loc[b] 

の1行目と3行目を返しdfます。これはdf[b]選択の場合と同じですが、ブールベクトルによる割り当てにも使用できます。

df.loc[b, 'name'] = 'Mary', 'John'

df.iloc [:,:]はすべての行と列と同等ですか?
Alvis 2017年

それはそうdf.loc[:, :]です。全体の値を再割り当てしDataFrameたり、ビューを作成したりするために使用できます。
JoeCondron

こんにちは、locとilocが従来の括弧()の間の通常のメソッドとしてではなく、角括弧[]の間にパラメーターを取る理由を知っていますか?
マリンガランティン

119

私の意見では、欠落している値のみのDataFrameを使用しているため、受け入れられた回答は混乱を招きます。私も長期好きではない位置ベースのため.iloc、代わりに、好む場所整数、それははるかに記述的で、まさにとして.ilocの略です。キーワードはINTEGERです.iloc-INTEGERSが必要です。

詳細については、サブセットの選択に関する非常に詳細なブログシリーズを参照してください


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

ので.ixISは廃止我々は唯一の間の違いに焦点を当てます.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'

6
うわー、これはプログラミングのトピックで遭遇した非常に明確で明快な説明の1つでした。行または列で機能する通常のインデックス付けについて最後に説明したのは、locとilocがある理由の1つです。方法。データキャンプコースでその警告に出くわしました。a。)df.columnsとdf.indexは何を返しますか?文字列のリストですか?リストの場合、このdf.columns [[2,4]]のような2つの要素にリストでアクセスできますか?b。)df.columnsでget_loc()を呼び出すことはできますか?c。)ilocの場合、なぜdf ['age']> 30.valuesを呼び出す必要があるのですか?
pragun

私が今まで見た中で最高のアンサー。
最大

これは本当に良い答えです。ixにはあまり影響を与えないのが好きでした。ありがとう。
オマベナ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.