これら3つのスライス方法がどのように異なるのか、誰かが説明できますか?
ドキュメント 、および これら答え を見ましたが、3つの違いについては説明できません。私にとっては、スライスのレベルが低いため、大部分は互換性があります。
たとえば、DataFrame
の最初の5行を取得したいとします。これら3つすべてが機能するのはどうしてですか。
df.loc[:5]
df.ix[:5]
df.iloc[:5]
用途の違いが明確な3つのケースを誰かが提示できますか?
注:pandasバージョン0.20.0以降では、ix
name__は 非推奨 であり、代わりにloc
name__およびiloc
name__の使用が推奨されます。 ix
name__を説明するこの回答の一部は、以前のバージョンのパンダのユーザーの参照としてそのまま残しました。 ix
name __の代替を示す例を以下に追加しました。
まず、3つの方法の要約を次に示します。
loc
name__は、インデックスから特定のlabelsを持つ行(または列)を取得します。iloc
name__は、インデックス内の特定のpositionsで行(または列)を取得します(したがって、整数のみを受け取ります)。ix
name__は通常、loc
name__のように振る舞いますが、ラベルがインデックスに存在しない場合はiloc
name__のように振る舞います。ix
name__を使用するのが少し面倒になる可能性があるいくつかの微妙な点に注意することが重要です。
インデックスが整数型の場合、ix
name__はラベルベースのインデックス付けのみを使用し、位置ベースのインデックス付けにフォールバックしません。ラベルがインデックスにない場合、エラーが発生します。
インデックスにonly整数が含まれていない場合、整数を指定すると、ix
name__はラベルベースのインデックスではなく、位置ベースのインデックスをすぐに使用します。ただし、ix
name__に別の型(文字列など)が指定されている場合は、ラベルベースのインデックス付けを使用できます。
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]
と同じSeriesを返すことに注意してください。これは、位置を処理するのではなく、最初にラベルを探すためです(s
name__のインデックスは整数型です)。
インデックスにない整数ラベル(たとえば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
上記の微妙な点により、s.ix[:6]
は、loc
name__のように動作しようとしますが、インデックスで6
が見つからないため、KeyErrorが発生します。インデックスは整数型ix
name__であるため、iloc
name__のように動作することはありません。
ただし、インデックスが混合型である場合、整数ix
name__を指定すると、KeyErrorが発生する代わりに、すぐにiloc
name__のように動作します。
>>> 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
name__は引き続き整数以外を受け入れ、loc
name__のように動作することに注意してください。
>>> s2.ix[:'c'] # behaves like loc given non-integer
a NaN
b NaN
c NaN
一般的なアドバイスとして、ラベルを使用してのみインデックスを作成する場合、または整数位置を使用してのみインデックスを作成する場合は、loc
name__またはiloc
name__を使用して、予期しない結果を避けます。ix
name__は使用しないでください。
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
pandas(0.20.0以前)の以前のバージョンでは、ix
name__を使用すると、これを非常にきれいに行うことができます。ラベルで行を、位置で列をスライスできます(列については、ix
name__がデフォルトでposition- 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
name__と別のメソッドのヘルプを使用してこの結果を達成できます。
>>> 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
name__を使用したスライスはエンドポイントを除外するため、行 'c'が必要な場合はこの値に1を追加する必要があることに注意してください。
パンダのドキュメントにはさらに例があります here 。
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'
列の次の2行は
df.loc['b':, 'date'] # equivalent to df.iloc[1:, 1]
等々。さて、おそらくDataFrame
のデフォルトの行と列のインデックスは0からの整数であり、この場合iloc
とloc
は同じように働くことを指摘する価値があります。これが、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]
df
の1行目と3行目を返します。これは選択のためのdf[b]
と同等ですが、ブールベクトルによる代入にも使用できます。
df.loc[b, 'name'] = 'Mary', 'John'
私の意見では、受け入れられた答えは紛失した値だけを持つDataFrameを使っているので、混乱を招きます。また、.iloc
の 位置ベースの という用語は好きではありません。代わりに、 整数の位置 を使ってください。.iloc
の意味がわかりやすいからです。キーワードはINTEGERです - .iloc
はINTEGERSを必要とします。
詳細については、私の非常に詳細な ブログシリーズ サブセットの選択を参照してください。
.ix
は非推奨なので、.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'])
bold 内のすべての単語はラベルです。 列 には、ラベルage
、color
、food
、height
、score
、およびstate
が使用されます。他のラベルJane
、Nick
、Aaron
、Penelope
、Dean
、Christina
、Cornelia
は、 index に使用されます。
DataFrame内の特定の行を選択する主な方法は、.loc
および.iloc
インデクサを使用することです。これらの各インデクサーを使用して列を同時に選択することもできますが、今のところは単に行に集中する方が簡単です。また、各インデクサーは、選択するために名前のすぐ後に続く一連の大括弧を使用します。
最初に、インデックスまたは列ラベルによってデータを選択するだけの.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を返します。
スライス表記で.locを使用して複数の行を選択する
スライス表記は、start、stop、stepの値によって定義されます。ラベルでスライスすると、パンダは戻り値にストップ値を含めます。以下のスライスは、アロンからディーンまでを含みます。そのステップサイズは明示的に定義されていませんが、デフォルトは1です。
df.loc['Aaron':'Dean']
複雑なスライスはPythonのリストと同じ方法で取得できます。
それでは.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を返します。
スライス表記を使用して.ilocで複数行を選択する
df.iloc[:5:3]
両方の.loc/.iloc
の優れた能力の1つは、行と列の両方を同時に選択できることです。上記の例では、すべての列が各選択から返されました。行と同じ入力タイプの列を選択できます。行と列の選択を コンマ で区切るだけです。
たとえば、次のように、列の高さ、スコア、および状態だけを使用して、行Jane、およびDeanを選択できます。
df.loc[['Jane', 'Dean'], 'height':]
これは行にラベルのリストを使い、列にスライス表記を使う
整数だけを使用して、.iloc
で同様の操作を自然に行うことができます。
df.iloc[[1,4], 2]
Nick Lamb
Dean Cheese
Name: food, dtype: object
.ix
はラベルと整数位置で同時に選択をするために使用されましたが、それは便利ですが混乱を招き、時々あいまいになりました。ラベルと整数位置を組み合わせて選択する必要がある場合は、両方のラベルと整数位置を選択する必要があります。
たとえば、行2と4とともに行Nick
とCornelia
を選択する場合は、次のように整数をラベルに変換することで.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歳以上のすべての行を見つけて、food
列とscore
列だけを返すことに興味がある場合は、次のようにします。
df.loc[df['age'] > 30, ['food', 'score']]
これを.iloc
で複製することはできますが、ブール級数を渡すことはできません。このようにブール値のSeriesをでこぼこの配列に変換する必要があります。
df.iloc[(df['age'] > 30).values, [2, 4]]
列選択だけに.loc/.iloc
を使用することは可能です。このようにコロンを使用してすべての行を選択できます。
df.loc[:, 'color':'score':2]
[]
は、行と列も選択できますが、同時には選択できません。ほとんどの人は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']]
あまり知られていないのは、スライス表記が使用されている場合、選択は行ラベルまたは整数位置によって行われるということです。これは非常に混乱を招くものであり、私が使用することはほとんどありませんが、機能します。
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'