最近、私の安全な場所(R)からPythonに分岐し始めました。そしてPandas
のセルのローカライズ/選択に少し混乱しています。私はドキュメンテーションを読みましたが、さまざまなローカライズ/選択オプションの実際的な意味を理解するのに苦労しています。
.loc
の代わりに.iloc
または.ix
を使用する必要があるのはなぜですか?.loc
、iloc
、at
、およびiat
は、.ix
が提供できないある程度の正確さを保証する可能性があることを理解していますが、.ix
が全面的に最速の解決策となる傾向があるところも読みました。.ix
以外のものを利用することの背後にある現実世界のベストプラクティスの推論について説明してください。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
インデクサーが優先されます。
pandas
が非推奨になったことを考えると、ix
0.20
用に更新されました。これは、loc
、iloc
、at
、iat
、set_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_value
とtakable=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)
パンダがDataFrameから選択する2つの主な方法があります。
資料では、整数位置を参照するために用語位置を使用します。私はそれが紛らわしいと感じるので私はこの専門用語が好きではありません。整数位置はより説明的で、正確には.iloc
が表すものです。ここでのキーワードはINTEGERです - 整数位置で選択するときは整数を使わなければなりません。
要約を表示する前に、すべて確認しましょう。
パンダには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'])
太字内の単語はすべてラベルです。ラベルage
name__、color
name__、food
name__、height
name__、score
name__、およびstate
name__は、列に使用されます。他のラベルJane
name__、Nick
name__、Aaron
name__、Penelope
name__、Dean
name__、Christina
name__、Cornelia
name__は、行のラベルとして使用されます。まとめて、これらの行ラベルはインデックスとして知られています。
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
name__とCornelia
name__を選択する場合は、次のように整数をラベルに変換して.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
name__およびscore
name__列のみを返すことに関心がある場合は、次のようにします。
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'
.at
と.iat
による選択.at
による選択は、.loc
とほぼ同じですが、DataFrame内の単一の「セル」のみを選択します。通常、このセルをスカラー値と呼びます。 .loc
を使用するには、行と列の両方のラベルをコンマで区切って渡します。
df.at['Christina', 'color']
'black'
.iat
による選択は.iloc
とほぼ同じですが、単一のスカラー値のみを選択します。行位置と列位置の両方に整数を渡す必要があります
df.iat[2, 5]
'FL'
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
この小さな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を使用すると単一のスカラーのみで管理できます。
:-)