今回は、Pandasの要素抽出の仕方をまとめていきます。

本記事では

  • 属性(attribute)を用いた方法
  • 属性を使わない方法  

について解説します。

loc, iloc, at, iat

場所指定の要素抽出を行うためにはDataFrame、Series両方に存在する loc, iloc, at, iat 属性(attribute)を使うのが一般的です。

loc系と at系の違いは loc系は複数要素を抽出できるが、at系は1つのみ という点で、i系とその他の違いは 絶対座標で指定するか、ラベル名で指定するかとなります。

  loc iloc at iat
絶対座標指定 × ×
ラベル名指定 × ×
複数要素指定 × ×
スライス表記 × ×

loc

locはスライス表記ありで、ラベル名を指定をします。ラベル名が連番だったり値だったりした場合も同様です。

loc[<インデックスラベル>, <カラムラベル>]の順に指定します。ラベルには、スライス表記を使うことができます。例えば、"A":"D"のように指定することでA~Dまでを抽出できます。NumPyのスライス表記と似ていますが、スライス対象に最後の”D”が含まれることに注意してください。

NumPyのスライシングについて興味のある方は、以下の記事を参考にしてください。

NumPy配列のスライシング機能の使い方 features/numpy-slicing.html

実際に使用例を見ていきましょう。

In [1]: import pandas as pd

In [2]: import numpy as np

In [4]: df = pd.DataFrame(np.arange(20).reshape(5,4), index=["Tokyo","Osaka","Fukuoka","Nagano", "Nara"],columns=["A","B","C","D"])

In [5]: df
Out[5]:
          A   B   C   D
Tokyo     0   1   2   3
Osaka     4   5   6   7
Fukuoka   8   9  10  11
Nagano   12  13  14  15
Nara     16  17  18  19

In [6]: df.loc["Tokyo","B"] # インデックスが"Tokyo"でカラムが"B"の要素
Out[6]: 1

In [7]: df.loc["Osaka":"Nara", "B"] # "Osaka"から"Nara"までのスライス
Out[7]:
Osaka       5
Fukuoka     9
Nagano     13
Nara       17
Name: B, dtype: int64

In [9]: df.loc["Fukuoka", "B":"D"] # "B"から"D"までのスライス
Out[9]:
B     9
C    10
D    11
Name: Fukuoka, dtype: int64

In [10]: df.loc["Osaka":"Nagano", "A":"C"] # 両方の軸に対してスライス
Out[10]:
          A   B   C
Osaka     4   5   6
Fukuoka   8   9  10
Nagano   12  13  14

In [18]: df.loc[:, "D"] # "D"列全部
Out[18]:
Tokyo       3
Osaka       7
Fukuoka    11
Nagano     15
Nara       19
Name: D, dtype: int64

スライス表記はNumPyやPythonのリストとは異なり、終点に指定した値も範囲に含まれまれていることが確認できます。

iloc

同様のことをilocでもやってみます。こちらはNumPyでのスライス表記と同様、終点に指定した端点は含まれない ので注意してください。

In [11]: df
Out[11]:
          A   B   C   D
Tokyo     0   1   2   3
Osaka     4   5   6   7
Fukuoka   8   9  10  11
Nagano   12  13  14  15
Nara     16  17  18  19

In [12]: df.iloc[0,1] # "Tokyo"で"B"
Out[12]: 1

In [14]: df.iloc[1:4, 0] # loc["Osaka":"Nara","B"]
Out[14]:
Osaka       4
Fukuoka     8
Nagano     12
Name: A, dtype: int64

In [15]: df.iloc[2, 1:] # loc["Fukuoka", "B":"D"]
Out[15]:
B     9
C    10
D    11
Name: Fukuoka, dtype: int64

In [16]: df.iloc[1:4, 0:3] # df.loc["Osaka":"Nagano", "A":"C"]
Out[16]:
          A   B   C
Osaka     4   5   6
Fukuoka   8   9  10
Nagano   12  13  14

In [17]: df.iloc[:, 3] # df.loc[:, "D"]
Out[17]:
Tokyo       3
Osaka       7
Fukuoka    11
Nagano     15
Nara       19
Name: D, dtype: int64

at

次はatです。at系は 1つの要素しか抜き出すことができない ことに注意してください。その他の使い方はlocと一緒です。

In [19]: df
Out[19]:
          A   B   C   D
Tokyo     0   1   2   3
Osaka     4   5   6   7
Fukuoka   8   9  10  11
Nagano   12  13  14  15
Nara     16  17  18  19

In [23]: df.at[["Fukuoka","Nagano"], "D"] # 複数要素の指定はできない
---------------------------------------------------------------------------
(エラーメッセージが表示される)
TypeError: '['Fukuoka', 'Nagano']' is an invalid key

In [24]: df.loc[["Fukuoka","Nagano"], "D"] # locだと問題なく動く
Out[24]:
Fukuoka    11
Nagano     15
Name: D, dtype: int64

In [25]: df.at["Nara","A"]
Out[25]: 16

iat

iatatと同様 単一要素しか指定できません 。他の使い方はilocと同様で、絶対座標で指定します。

In [26]: df
Out[26]:
          A   B   C   D
Tokyo     0   1   2   3
Osaka     4   5   6   7
Fukuoka   8   9  10  11
Nagano   12  13  14  15
Nara     16  17  18  19

In [27]: df.iat[0,1] # 0行目1列目
Out[27]: 1

In [28]: df.iat[1, 2] # 1行目2列目
Out[28]: 6

In [29]: df.iat[3,3] # 3行目3列目
Out[29]: 15

In [30]: df.iat[-1,-1] # 最終行目最終列目
Out[30]: 19

属性(attribute)を使わない方法

では次はloc,iloc,at,iatなどを使わない方法を紹介していきます。

列データを抜き出す

列データを抜き出すときはDataFrame[<列ラベル>]で抜き出せます。同じようにDataFrame.<列ラベル>でも可能です。

In [31]: df
Out[31]:
          A   B   C   D
Tokyo     0   1   2   3
Osaka     4   5   6   7
Fukuoka   8   9  10  11
Nagano   12  13  14  15
Nara     16  17  18  19

In [32]: df["A"]
Out[32]:
Tokyo       0
Osaka       4
Fukuoka     8
Nagano     12
Nara       16
Name: A, dtype: int64

In [33]: df.A
Out[33]:
Tokyo       0
Osaka       4
Fukuoka     8
Nagano     12
Nara       16
Name: A, dtype: int64

この場合、スライス表記は使えません。スライス表記はインデックスラベルに対して有効です。

In [34]: df["A":"C"]
---------------------------------------------------------------------------
(エラーメッセージが表示される)

KeyError: 'A'

カラム名が連番であっても同じようにできます。
ただし、.を使った表記は使えません。

In [35]: df.columns = range(4)

In [36]: df
Out[36]:
          0   1   2   3
Tokyo     0   1   2   3
Osaka     4   5   6   7
Fukuoka   8   9  10  11
Nagano   12  13  14  15
Nara     16  17  18  19

In [37]: df.0 # 連番になると.表記は使えない
  File "<ipython-input-37-5784c4767bed>", line 1
    df.0
       ^
SyntaxError: invalid syntax

In [38]: df[0]
Out[38]:
Tokyo       0
Osaka       4
Fukuoka     8
Nagano     12
Nara       16
Name: 0, dtype: int64

In [39]: df[1]
Out[39]:
Tokyo       1
Osaka       5
Fukuoka     9
Nagano     13
Nara       17
Name: 1, dtype: int64

複数行を抜き出す

複数行を抜き出すときは先ほどのDataFrame[スライス表記]でできます。

In [40]: df
Out[40]:
          0   1   2   3
Tokyo     0   1   2   3
Osaka     4   5   6   7
Fukuoka   8   9  10  11
Nagano   12  13  14  15
Nara     16  17  18  19

In [41]: df[0:1]
Out[41]:
       0  1  2  3
Tokyo  0  1  2  3

In [42]: df[:4]
Out[42]:
          0   1   2   3
Tokyo     0   1   2   3
Osaka     4   5   6   7
Fukuoka   8   9  10  11
Nagano   12  13  14  15

In [43]: df[2:3]
Out[43]:
         0  1   2   3
Fukuoka  8  9  10  11

In [44]: df[2:4]
Out[44]:
          0   1   2   3
Fukuoka   8   9  10  11
Nagano   12  13  14  15

まとめ

今回は、要素の位置を指定した形での要素抽出の仕方についてまとめました。

ラベル表記のときに終点となる端点が含まれる点が他のオブジェクトにおけるスライス表記と異なる点でしたが、それ以外では大きな違いを感じることなく要素抽出ができるようになっているはずです。

ちなみに、属性(attribute)として同様の機能を果たすixというものがありますが、これは公式ドキュメントでは非推奨(deprecated)となっています。ラベルづけと連番のインデックスが混在しているときなどには効果を発揮しますが、あまり使わない方が良いでしょう。

参考