この2つのスライス方法の違いを説明していただけますか?ドキュメント以前にも同様の質問を見たことがあります(1、2) ですが、まだその違いが理解できません。私にとっては、これらはスライスの下位レベルにあるため、大部分は互換性があるように見えます。
たとえば、 の最初の 5 行を取得したいとしますDataFrame
。この 2 つはどのように機能するのでしょうか。
df.loc[:5]
df.iloc[:5]
用途の違いがより明確な事例を誰か紹介してもらえませんか?
かつては、これら 2 つの関数がどう違うのか知りたかったのですdf.ix[:5]
が、ix
pandas 1.0 では削除されたので、もう気にしません。
ベストアンサー1
ラベルと場所
2 つの方法の主な違いは次のとおりです。
loc
特定のラベルを持つ行 (および/または列) を取得します。iloc
整数位置の行 (および/または列) を取得します。
s
説明のために、非単調な整数インデックスを持つ一連の文字を考えてみましょう。
>>> s = pd.Series(list("abcdef"), index=[49, 48, 47, 0, 1, 2])
49 a
48 b
47 c
0 d
1 e
2 f
>>> s.loc[0] # value at index label 0
'd'
>>> s.iloc[0] # value at index location 0
'a'
>>> s.loc[0:1] # rows at index labels between 0 and 1 (inclusive)
0 d
1 e
>>> s.iloc[0:1] # rows at index location between 0 and 1 (exclusive)
49 a
さまざまなオブジェクト間s.loc
および渡されるときの相違点と類似点の一部を次に示します。s.iloc
<オブジェクト> | 説明 | s.loc[<object>] |
s.iloc[<object>] |
---|---|---|---|
0 |
単品 | インデックスラベル の値0 (文字列'd' ) |
インデックス位置0の値(文字列'a' ) |
0:1 |
スライス | 2行(ラベル0 と1 ) |
1行(最初の行は位置0) |
1:47 |
境界外のスライス | ゼロ行(空のシリーズ) | 5行(位置1以降) |
1:47:-1 |
負のステップのスライス | 3行(ラベル1 は に戻る47 ) |
ゼロ行(空のシリーズ) |
[2, 0] |
整数リスト | ラベルが指定された2行 | 指定された場所の2行 |
s > 'e' |
ブールシリーズ(どの値がプロパティを持っているかを示す) | 1行(含む'f' ) |
NotImplementedError |
(s>'e').values |
ブール配列 | 1行(含む'f' ) |
と同じloc |
999 |
int オブジェクトがインデックスにありません | KeyError |
IndexError (立入禁止で) |
-1 |
int オブジェクトがインデックスにありません | KeyError |
最後の値を返すs |
lambda x: x.index[3] |
シリーズに適用される呼び出し可能オブジェクト (ここではインデックスの3番目の項目を返します) | s.loc[s.index[3]] |
s.iloc[s.index[3]] |
loc
のラベル クエリ機能は整数インデックスをはるかに超えているため、さらにいくつかの例を紹介する価値があります。
インデックスに文字列オブジェクトが含まれるシリーズを次に示します。
>>> s2 = pd.Series(s.index, index=s.values)
>>> s2
a 49
b 48
c 47
d 0
e 1
f 2
はラベルベースなのでloc
、 を使用して Series の最初の値を取得できますs2.loc['a']
。また、整数以外のオブジェクトでスライスすることもできます。
>>> s2.loc['c':'e'] # all rows lying between 'c' and 'e' (inclusive)
c 47
d 0
e 1
DateTime インデックスの場合、ラベルで取得するために正確な日付/時刻を渡す必要はありません。例:
>>> s3 = pd.Series(list('abcde'), pd.date_range('now', periods=5, freq='M'))
>>> s3
2021-01-31 16:41:31.879768 a
2021-02-28 16:41:31.879768 b
2021-03-31 16:41:31.879768 c
2021-04-30 16:41:31.879768 d
2021-05-31 16:41:31.879768 e
次に、2021 年 3 月/4 月の行を取得するには、次のものだけが必要です。
>>> s3.loc['2021-03':'2021-04']
2021-03-31 17:04:30.742316 c
2021-04-30 17:04:30.742316 d
行と列
loc
DataFramesでもiloc
Series と同じように機能します。どちらの方法でも列と行を一緒に処理できることに注目すると便利です。
タプルが指定されると、最初の要素が行のインデックス付けに使用され、存在する場合は 2 番目の要素が列のインデックス付けに使用されます。
以下に定義された DataFrame を考えてみましょう。
>>> import numpy as np
>>> df = pd.DataFrame(np.arange(25).reshape(5, 5),
index=list('abcde'),
columns=['x','y','z', 8, 9])
>>> df
x y z 8 9
a 0 1 2 3 4
b 5 6 7 8 9
c 10 11 12 13 14
d 15 16 17 18 19
e 20 21 22 23 24
たとえば次のようになります。
>>> df.loc['c': , :'z'] # rows 'c' and onwards AND columns up to 'z'
x y z
c 10 11 12
d 15 16 17
e 20 21 22
>>> df.iloc[:, 3] # all rows, but only the column at index location 3
a 3
b 8
c 13
d 18
e 23
loc
場合によっては、行と列のラベルと位置のインデックス方法を混在させて、との機能を何らかの方法で組み合わせる必要がありますiloc
。
たとえば、次の DataFrame を考えてみましょう。行を 'c' までスライスし、最初の 4 列を取得する最適な方法は何でしょうか。
>>> import numpy as np
>>> df = pd.DataFrame(np.arange(25).reshape(5, 5),
index=list('abcde'),
columns=['x','y','z', 8, 9])
>>> df
x y z 8 9
a 0 1 2 3 4
b 5 6 7 8 9
c 10 11 12 13 14
d 15 16 17 18 19
e 20 21 22 23 24
iloc
別の方法を使用すると、この結果を達成できます。
>>> df.iloc[:df.index.get_loc('c') + 1, :4]
x y z 8
a 0 1 2 3
b 5 6 7 8
c 10 11 12 13
get_loc()
は、「このインデックス内のラベルの位置を取得する」ことを意味するインデックス メソッドです。スライスはiloc
エンドポイントを除くため、行 'c' も必要な場合はこの値に 1 を追加する必要があることに注意してください。