Pandasによるデータの基本確認と抽出方法のまとめ

データ分析の分野で、Pythonは今や確固たる地位を築いています。

それを支えるのが、NumPyPandasをはじめとするPythonの豊富なライブラリ群です。

Pandasをマスターすれば、テーブル状のデータに対して、フィルタリング・集計をはじめとする、ありとあらゆる操作を自由自在に行うことが出来ます。反面、Pandasはとにかく行うことの出来る作業が多く、それゆえに全てを覚えようというのは現実的ではありません。

そこで、当ブログではユースケース毎(データの抽出・集計・ソートetc)に実現する手段を素早く見つけ、解決できるようなチートシートを用意する予定です。とりわけ、本記事はその第一弾です。

https://datascientist-toolbox.com/wp-content/uploads/2019/09/man.png
りーぐる

今回は初回なので、Pandasの扱うデータ構造について簡単におさらいしてみるよ

Pandasのデータ構造

pandasはテーブル形式の不均一なデータを扱うために設計されています。

ここでは、pandasを利用する上で最も基礎となるシリーズ(Series)とデータフレーム(DataFrame)について簡単におさらいしましょう。

https://datascientist-toolbox.com/wp-content/uploads/2019/09/man.png
りーぐる

チートシートシリーズは、初めての方向けの記事ではないので腰を据えて学びたい場合は、体系的に学べる文献やWebで学習することをおすすめします!

シリーズ(Series)

シリーズは、平たくいうとインデックス付きの配列です。

シリーズは連続した値(values)とそれに関連付けられたインデックス(index)の配列で構成されています。

インデックスは、何も指定しなければ上記のようにユニークな0から始まる連番が振られますが、作成時に明示的に指定することももちろんできます。

また、インデックスはデータベースでいうところのprimary_keyとは異なるので、必ずしも一意である必要はありません。

データを扱う上で、データ型には常に気を配りましょう。valuesに入るデータは、同一のデータ型をもち、意味的にまとまりのあるものを扱うのが基本です。

データフレーム(DataFrame)

データフレームは、テーブル形式のデータ構造をもつpandasで最も重要なデータ構造です。

複数のカラム(columns)に対応付けられたデータ列(values)と、それらに関連付けられたインデックス(index)の配列で構成されています。

各カラム単位では、同一の型・意味的にまとまりのあるデータを扱うのが基本ですが、カラム間では別々のデータ型を扱うことが可能です

データフレームからカラムを抽出すると、シリーズ(Series)が得られます。

pandasではカラム名に日本語を付けることもできるので、必要に応じてわかりやすい名前をつけましょう。但しプログラミングで日本語を使う場合は、日本語起因のエラーがないか、気を配ることが重要です。

データの基本情報を確認する

続いて作成したシリーズやデータフレームに対して、データ型やメモリ使用量など、いくつかの基本情報を確認する方法をおさらいします。

pandasによるデータ分析には、ブラウザ上で逐一データの状態を確認しながら作業が行えるjupyter notebookが大変便利です。特にデータ処理パイプラインを作る前の、トライ&エラーの効率が上がることが利点です。

当ブログでも、pandas等を使ったデータ分析ではjupyter notebook環境で動作するコードを掲載します。ここではjupyter notebookの導入については割愛させていただきます。

パッケージのインストール

Pythonの環境構築にAnacondaディストリビューションを利用した場合は、既にpandasがインストールされています。個別にインストールしている場合は、下記によりpandasのインストールを行いましょう。

$ pip install pandas

pandasパッケージのインポート

はじめにpandasパッケージのインポートを行います。pandasパッケージは「pd」という名前でインポートされるのが慣例です。

他者とコラボレーションする際は、名前を統一しておくことが望ましいのでpdに合わせておきましょう。

jupyter notebookはセル単位でコードの実行を行います。実行イメージは下記の通りです。

In [1]やIn [2]はコードの実行履歴、Out[2]はIn[2]に対応する出力履歴です。当ブログでは、JupyterNotebookにより実行するコードは下記のように示します。

In [1]:
import pandas as pd
In [2]:
s = pd.Series([1, 2 ,3])
s
Out[2]:
0    1
1    2
2    3
dtype: int64

データフレームの読み込み

データフレームの情報を調べるにあたって、程よいサイズのデータセットを扱いたいので、ここではUC Irvine Machine Learning Repositoryに公開されているオンライン購買データを読み込みましょう。

In [1]:
import pandas as pd
import requests

# UC Irvine Machine Learning
url = "http://archive.ics.uci.edu/ml/machine-learning-databases/00352/Online%20Retail.xlsx"
response = requests.get(url)

# カレントディレクトリに"onlineRetail.xls"という名前で保存
output = open("onlineRetail.xls", 'wb')
output.write(response.content)
output.close()

# Excelファイルをpandasに取り込む
transaction = pd.ExcelFile("onlineRetail.xls")
# parseメソッドで"Online Retail"シートのデータフレームを作成する
transaction_table = transaction.parse('Online Retail')

データフレームを作成したら、まずは内容を確認しましょう。Jupyter Notebookの利点は、逐一自分の行った処理が正しいかエディタ上で確認できることです。

head()メソッドを使えば、データフレームの先頭5行を表示できます。

In [2]:
transaction_table.head()
Out[2]:
InvoiceNo StockCode Description Quantity InvoiceDate UnitPrice CustomerID Country
0 536365 85123A WHITE HANGING HEART T-LIGHT HOLDER 6 2010-12-01 08:26:00 2.55 17850.0 United Kingdom
1 536365 71053 WHITE METAL LANTERN 6 2010-12-01 08:26:00 3.39 17850.0 United Kingdom
2 536365 84406B CREAM CUPID HEARTS COAT HANGER 8 2010-12-01 08:26:00 2.75 17850.0 United Kingdom
3 536365 84029G KNITTED UNION FLAG HOT WATER BOTTLE 6 2010-12-01 08:26:00 3.39 17850.0 United Kingdom
4 536365 84029E RED WOOLLY HOTTIE WHITE HEART. 6 2010-12-01 08:26:00 3.39 17850.0 United Kingdom

head(3)で先頭3行、head(10)で先頭10行のように引数で取得する行数を制御できます。また、tail()メソッドではデータフレームの末尾n行を取得できます。

https://datascientist-toolbox.com/wp-content/uploads/2019/09/man.png
りーぐる

データフレームに変更を加えるたびに、本当にデータを壊していないか調べるのは重要だよ。len()でデータフレームの行数を調べるだけで防げることもある。

データフレームの構成要素の表示

データフレームのインデックスにはindex、カラムにはcolumnsでアクセスでき、それぞれインデックスオブジェクトが戻されます。

In [3]:
transaction_table.index
Out[3]:
RangeIndex(start=0, stop=541909, step=1)
In [4]:
transaction_table.columns
Out[4]:
Index(['InvoiceNo', 'StockCode', 'Description', 'Quantity', 'InvoiceDate',
       'UnitPrice', 'CustomerID', 'Country'],
      dtype='object')

データの値はvalues属性により取得でき、データフレーム中のデータが2次元のndarray(NumPy配列)が戻されます。

In [5]:
transaction_table.values
Out[5]:
array([[536365, '85123A', 'WHITE HANGING HEART T-LIGHT HOLDER', ...,
        2.55, 17850.0, 'United Kingdom'],
       [536365, 71053, 'WHITE METAL LANTERN', ..., 3.39, 17850.0,
        'United Kingdom'],
       [536365, '84406B', 'CREAM CUPID HEARTS COAT HANGER', ..., 2.75,
        17850.0, 'United Kingdom'],
       ...,
       [581587, 23254, 'CHILDRENS CUTLERY DOLLY GIRL ', ..., 4.15,
        12680.0, 'France'],
       [581587, 23255, 'CHILDRENS CUTLERY CIRCUS PARADE', ..., 4.15,
        12680.0, 'France'],
       [581587, 22138, 'BAKING SET 9 PIECE RETROSPOT ', ..., 4.95,
        12680.0, 'France']], dtype=object)

メタ情報の表示

info()メソッドを使えば、データフレームのメタ情報が一度に得られます。

In [6]:
transaction_table.info()
Out[6]:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 541909 entries, 0 to 541908
Data columns (total 8 columns):
InvoiceNo      541909 non-null object
StockCode      541909 non-null object
Description    540455 non-null object
Quantity       541909 non-null int64
InvoiceDate    541909 non-null datetime64[ns]
UnitPrice      541909 non-null float64
CustomerID     406829 non-null float64
Country        541909 non-null object
dtypes: datetime64[ns](1), float64(2), int64(1), object(4)
memory usage: 33.1+ MB
infoメソッドから分かること

  • インデックスの総数
  • カラム名
  • 各カラムの欠損値を除いたデータ数
  • 各カラムのデータ型
  • データフレームのメモリの使用量

各カラム欠損数の確認

isnull()メソッドを使用することで、データフレームの各セルに欠損値が含まれているかどうかの真理値を得ることができます。sum()メソッドと組み合わせることで、各カラムの欠損値の総数を取得できます。

In [7]:
transaction_table.isnull().sum()
Out[7]:
InvoiceNo           0
StockCode           0
Description      1454
Quantity            0
InvoiceDate         0
UnitPrice           0
CustomerID     135080
Country             0
dtype: int64

infoメソッドからも欠損数を算出することは可能ですが、データ分析において欠損は特別な意味を持つので、専用に確認する方法も知っておくと便利です。

要約統計量の表示

describeメソッドで、データフレームの様々な要約統計量を一度に取得できます。データの概要を掴むのに非常に役立つ必須メソッドです。

In [8]:
transaction_table.describe(include='all')
Out[8]:
InvoiceNo StockCode Description Quantity InvoiceDate UnitPrice CustomerID Country
count 541909.0 541909 540455 541909.000000 541909 541909.000000 406829.000000 541909
unique 25900.0 4070 4223 NaN 23260 NaN NaN 38
top 573585.0 85123A WHITE HANGING HEART T-LIGHT HOLDER NaN 2011-10-31 14:41:00 NaN NaN United Kingdom
freq 1114.0 2313 2369 NaN 1114 NaN NaN 495478
first NaN NaN NaN NaN 2010-12-01 08:26:00 NaN NaN NaN
last NaN NaN NaN NaN 2011-12-09 12:50:00 NaN NaN NaN
mean NaN NaN NaN 9.552250 NaN 4.611114 15287.690570 NaN
std NaN NaN NaN 218.081158 NaN 96.759853 1713.600303 NaN
min NaN NaN NaN -80995.000000 NaN -11062.060000 12346.000000 NaN
25% NaN NaN NaN 1.000000 NaN 1.250000 13953.000000 NaN
50% NaN NaN NaN 3.000000 NaN 2.080000 15152.000000 NaN
75% NaN NaN NaN 10.000000 NaN 4.130000 16791.000000 NaN
max NaN NaN NaN 80995.000000 NaN 38970.000000 18287.000000 NaN

describeメソッドはデフォルトでは数値データの要約統計量のみを表示します。引数に”all”を指定することで、数値データ以外の統計量も表示しています。

数値データ・カテゴリデータ・日付データでそれぞれ出力する要約統計量に差異があるため、表示されない要約統計量の値はNaNとなります。

カラムのデータ型確認

infoメソッドにより各カラムのデータ型が確認できましたが、object型には注意が必要です。object型を持つカラムにはstr型をはじめとして、複数のデータ型を含む可能性があります。

In [9]:
transaction_table['InvoiceNo'].map(type(str)).value_counts()
Out[9]:
<class 'int'>    532618
<class 'str'>      9291
Name: InvoiceNo, dtype: int64

上記のように、map()メソッドとvalue_counts()メソッドを組み合わせることでカラム内に複数のデータ型が存在する場合でも、全てのデータ型とデータ数をセットで表示できます。

全ユニーク値の表示

データを捉える上で要約統計量だけでなく、値そのものを確認することも重要です。unique()メソッドにより、全ユニーク値を確認することが可能です。

In [10]:
transaction_table['Country'].unique()
Out[10]:
array(['United Kingdom', 'France', 'Australia', 'Netherlands', 'Germany',
       'Norway', 'EIRE', 'Switzerland', 'Spain', 'Poland', 'Portugal',
       'Italy', 'Belgium', 'Lithuania', 'Japan', 'Iceland',
       'Channel Islands', 'Denmark', 'Cyprus', 'Sweden', 'Austria',
       'Israel', 'Finland', 'Bahrain', 'Greece', 'Hong Kong', 'Singapore',
       'Lebanon', 'United Arab Emirates', 'Saudi Arabia',
       'Czech Republic', 'Canada', 'Unspecified', 'Brazil', 'USA',
       'European Community', 'Malta', 'RSA'], dtype=object)

ここまでで、データの基本情報の代表的な確認項目を挙げました。

このようなデータ確認はデータを受領するたびに毎度行う作業です。初期確認の段階で明確な確認観点をもち、効率的にデータを把握することができれば、データ分析はより効率よく、信頼性の高いものになります。

例えば今回確認した中でも、CustomerIDを数値として扱ってしまっていたり、2つのカラムに欠損が確認されたり、数量を表すQuantityにマイナス値が入っていたり…といったデータやデータの扱いに関する問題点が見えてくるでしょう。

データをさまざまな角度から把握することが、データ分析業務の第一歩です。

Pandasによるデータの選択

Pandasにはシリーズとデータフレームのデータ構造がありますが、シリーズはデータフレームを扱うことが出来れば、基本的には直感的に扱うことができるため、ここではデータフレームのデータ抽出方法についておはなしします。

カラム名によるインデックス参照

最も基本的な参照は、カラム名による1つまたは複数のカラムの選択です。先程作成したtransaction_tableをもう一度確認してみましょう。

In [11]:
transaction_table.head(3)
Out[11]:
InvoiceNo StockCode Description Quantity InvoiceDate UnitPrice CustomerID Country
0 536365 85123A WHITE HANGING HEART T-LIGHT HOLDER 6 2010-12-01 08:26:00 2.55 17850.0 United Kingdom
1 536365 71053 WHITE METAL LANTERN 6 2010-12-01 08:26:00 3.39 17850.0 United Kingdom
2 536365 84406B CREAM CUPID HEARTS COAT HANGER 8 2010-12-01 08:26:00 2.75 17850.0 United Kingdom

1つのカラムを取り出す

以下のようにインデックス参照を行うと、データフレームのカラムを取り出すことができます。

In [12]:
transaction_table['StockCode'].tail()
Out[12]:
541904    22613
541905    22899
541906    23254
541907    23255
541908    22138
Name: StockCode, dtype: object

出力が長くなるので、ここではtail()メソッドを使って末尾5行を表示するように制限しています。

このように単一のカラム名を文字列で指定して参照すると、シリーズ(Series)が戻されます。もし1つのカラムを持つデータフレームを戻したいのであれば、カラム名のリストを渡す必要があります

In [13]:
transaction_table[['StockCode']].tail()
Out[13]:
StockCode
541904 22613
541905 22899
541906 23254
541907 23255
541908 22138
https://datascientist-toolbox.com/wp-content/uploads/2019/09/man.png

シリーズとデータフレームでは使用可能なメソッドも異なるので、必要に応じてどちらのデータ構造を使うか選択しよう。

複数のカラムを取り出す

複数のカラムを取り出す場合は、1つのカラムをデータフレームで取り出す場合と同じ要領で複数のカラム名を持つリストを指定すればよいです。

In [14]:
transaction_table[['StockCode', 'UnitPrice']].tail()
Out[14]:
StockCode UnitPrice
541904 22613 0.85
541905 22899 2.10
541906 23254 4.15
541907 23255 4.15
541908 22138 4.95

ところで多くの連続したカラムを取り出したい場合、例えば以下のようにスライシングを使って取り出したいと考えるのではないでしょうか。

In [15]:
transaction_table['StockCode': 'UnitPrice']
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-17-f3525ca618da> in <module>
----> 1 transaction_table['StockCode': 'UnitPrice']

~/anaconda3/lib/python3.6/site-packages/pandas/core/frame.py in __getitem__(self, key)
   2674 
   2675         # see if we can slice the rows
-> 2676         indexer = convert_to_index_sliceable(self, key)
   2677         if indexer is not None:
   2678             return self._getitem_slice(indexer)

~/anaconda3/lib/python3.6/site-packages/pandas/core/indexing.py in convert_to_index_sliceable(obj, key)
   2324     idx = obj.index
   2325     if isinstance(key, slice):
-> 2326         return idx._convert_slice_indexer(key, kind='getitem')
   2327 
   2328     elif isinstance(key, compat.string_types):

~/anaconda3/lib/python3.6/site-packages/pandas/core/indexes/base.py in _convert_slice_indexer(self, key, kind)
   1724             """
   1725             if self.is_integer() or is_index_slice:
-> 1726                 return slice(self._validate_indexer('slice', key.start, kind),
   1727                              self._validate_indexer('slice', key.stop, kind),
   1728                              self._validate_indexer('slice', key.step, kind))

~/anaconda3/lib/python3.6/site-packages/pandas/core/indexes/base.py in _validate_indexer(self, form, key, kind)
   4143             pass
   4144         elif kind in ['iloc', 'getitem']:
-> 4145             self._invalid_indexer(form, key)
   4146         return key
   4147 

~/anaconda3/lib/python3.6/site-packages/pandas/core/indexes/base.py in _invalid_indexer(self, form, key)
   1861                         "indexers [{key}] of {kind}".format(
   1862                             form=form, klass=type(self), key=key,
-> 1863                             kind=type(key)))
   1864 
   1865     def get_duplicates(self):

TypeError: cannot do slice indexing on <class 'pandas.core.indexes.range.RangeIndex'> with these indexers [StockCode] of <class 'str'>

残念ながらこの方法では、エラーが起きます

このあと説明する通り、スライシングによるインデックス参照は、カラムではなく行のインデックス参照となります。

先程のコードを正しく実行するには、locを使って明示的に行・列それぞれに対する参照条件を含める必要があります。

In [16]:
transaction_table.loc[:, 'StockCode': 'UnitPrice'].tail()
Out[16]:
StockCode Description Quantity InvoiceDate UnitPrice
541904 22613 PACK OF 20 SPACEBOY NAPKINS 12 2011-12-09 12:50:00 0.85
541905 22899 CHILDREN’S APRON DOLLY GIRL 6 2011-12-09 12:50:00 2.10
541906 23254 CHILDRENS CUTLERY DOLLY GIRL 4 2011-12-09 12:50:00 4.15
541907 23255 CHILDRENS CUTLERY CIRCUS PARADE 4 2011-12-09 12:50:00 4.15
541908 22138 BAKING SET 9 PIECE RETROSPOT 3 2011-12-09 12:50:00 4.95

スライシングによるインデックス参照

カラム名によるインデックス参照で見た通り、データフレームに対して参照を1つだけ与えると、通常はカラムに対する選択となるのですが、スライシングを使った参照やブールインデックス参照では行に対する選択となります

これはおそらく利用シーンが多いので、Pandasによって利便性のために提供された機能ですが、混乱しがちなポイントなので、別で確認しておきましょう。

transaction_tableのインデックスを確認すると、0から始まり1刻みで541908まで存在することがわかります。

In [17]:
transaction_table.index
Out[17]:
RangeIndex(start=0, stop=541909, step=1)

データフレームの先頭から5行を取り出したいとき、これまでhead()メソッドを使って実現していましたが、同じことをスライシングによる参照を使うことでも実現できます。

In [18]:
transaction_table[:5]
Out[18]:
InvoiceNo StockCode Description Quantity InvoiceDate UnitPrice CustomerID Country
0 536365 85123A WHITE HANGING HEART T-LIGHT HOLDER 6 2010-12-01 08:26:00 2.55 17850.0 United Kingdom
1 536365 71053 WHITE METAL LANTERN 6 2010-12-01 08:26:00 3.39 17850.0 United Kingdom
2 536365 84406B CREAM CUPID HEARTS COAT HANGER 8 2010-12-01 08:26:00 2.75 17850.0 United Kingdom
3 536365 84029G KNITTED UNION FLAG HOT WATER BOTTLE 6 2010-12-01 08:26:00 3.39 17850.0 United Kingdom
4 536365 84029E RED WOOLLY HOTTIE WHITE HEART. 6 2010-12-01 08:26:00 3.39 17850.0 United Kingdom

ただしインデックスのラベルが数値の場合、インデックスのラベルによる参照なのか位置による参照なのか、判別が付きづらいので通常このような参照は推奨されないことに注意しましょう。

どちらの方法で参照しているのか、明示的に指定するのがベストプラクティスとされています。

2種類の指定方法

  • ラベルによる指定(loc):インデックスのラベルが0から4までを取得する
  • 位置による指定(iloc):先頭から5行目までを取得する

In [19]:
transaction_table.loc[:4]
Out[19]:
InvoiceNo StockCode Description Quantity InvoiceDate UnitPrice CustomerID Country
0 536365 85123A WHITE HANGING HEART T-LIGHT HOLDER 6 2010-12-01 08:26:00 2.55 17850.0 United Kingdom
1 536365 71053 WHITE METAL LANTERN 6 2010-12-01 08:26:00 3.39 17850.0 United Kingdom
2 536365 84406B CREAM CUPID HEARTS COAT HANGER 8 2010-12-01 08:26:00 2.75 17850.0 United Kingdom
3 536365 84029G KNITTED UNION FLAG HOT WATER BOTTLE 6 2010-12-01 08:26:00 3.39 17850.0 United Kingdom
4 536365 84029E RED WOOLLY HOTTIE WHITE HEART. 6 2010-12-01 08:26:00 3.39 17850.0 United Kingdom
In [20]:
transaction_table.iloc[:5]
Out[20]:
InvoiceNo StockCode Description Quantity InvoiceDate UnitPrice CustomerID Country
0 536365 85123A WHITE HANGING HEART T-LIGHT HOLDER 6 2010-12-01 08:26:00 2.55 17850.0 United Kingdom
1 536365 71053 WHITE METAL LANTERN 6 2010-12-01 08:26:00 3.39 17850.0 United Kingdom
2 536365 84406B CREAM CUPID HEARTS COAT HANGER 8 2010-12-01 08:26:00 2.75 17850.0 United Kingdom
3 536365 84029G KNITTED UNION FLAG HOT WATER BOTTLE 6 2010-12-01 08:26:00 3.39 17850.0 United Kingdom
4 536365 84029E RED WOOLLY HOTTIE WHITE HEART. 6 2010-12-01 08:26:00 3.39 17850.0 United Kingdom

ラベルによる指定のスライシングでは末尾を含み、位置による指定のスライシングでは末尾を含まないことに注意しましょう。

ブールインデックス参照

データフレームを扱う際、SQLのWHERE文にあたる「あるカラムについて特定の条件に当てはまるレコード(行)のみを抽出したい」というケースは多くあります。

このような場合、真偽値配列を使って取得する行を選択するブールインデックス参照が使われます。

ここでは数量がマイナスになっている異常なレコードを調べてみましょう。

In [21]:
transaction_table['Quantity'] < 0
Out[21]:
0         False
1         False
2         False
3         False
4         False
5         False
6         False
7         False
8         False
9         False
10        False
11        False
12        False
13        False
14        False
15        False
16        False
17        False
18        False
19        False
20        False
21        False
22        False
23        False
24        False
25        False
26        False
27        False
28        False
29        False
          ...  
541879    False
541880    False
541881    False
541882    False
541883    False
541884    False
541885    False
541886    False
541887    False
541888    False
541889    False
541890    False
541891    False
541892    False
541893    False
541894    False
541895    False
541896    False
541897    False
541898    False
541899    False
541900    False
541901    False
541902    False
541903    False
541904    False
541905    False
541906    False
541907    False
541908    False
Name: Quantity, Length: 541909, dtype: bool

このようにあるカラムに対して、数式を適用するとNumPy配列のようにブロードキャストが行われ、全てのレコードについて不等式評価が行われます。ここでは、0未満のレコードがTrue、0以上のレコードがFalseとなります。

Trueの部分のレコードのみを抽出するのが、ブールインデックス参照です。

In [22]:
transaction_table[transaction_table['Quantity'] < 0].head()
Out[22]:
InvoiceNo StockCode Description Quantity InvoiceDate UnitPrice CustomerID Country
141 C536379 D Discount -1 2010-12-01 09:41:00 27.50 14527.0 United Kingdom
154 C536383 35004C SET OF 3 COLOURED FLYING DUCKS -1 2010-12-01 09:49:00 4.65 15311.0 United Kingdom
235 C536391 22556 PLASTERS IN TIN CIRCUS PARADE -12 2010-12-01 10:24:00 1.65 17548.0 United Kingdom
236 C536391 21984 PACK OF 12 PINK PAISLEY TISSUES -24 2010-12-01 10:24:00 0.29 17548.0 United Kingdom
237 C536391 21983 PACK OF 12 BLUE PAISLEY TISSUES -24 2010-12-01 10:24:00 0.29 17548.0 United Kingdom

AND条件やOR条件を使ったより複雑なフィルタリングも、Pandasでは極めて簡単に実現できます。

In [23]:
from datetime import datetime

transaction_table[(transaction_table['InvoiceDate'] > datetime(2011, 3, 11)) &
                  (transaction_table['Quantity'] < 0)].head()
Out[23]:
InvoiceNo StockCode Description Quantity InvoiceDate UnitPrice CustomerID Country
117026 C546320 22467 GUMBALL COAT RACK -3 2011-03-11 09:39:00 2.55 12708.0 Germany
117027 C546320 22243 5 HOOK HANGER RED MAGIC TOADSTOOL -4 2011-03-11 09:39:00 1.65 12708.0 Germany
117032 C546323 22064 PINK DOUGHNUT TRINKET POT -2 2011-03-11 09:48:00 1.65 13975.0 United Kingdom
117033 C546323 22722 SET OF 6 SPICE TINS PANTRY DESIGN -5 2011-03-11 09:48:00 3.95 13975.0 United Kingdom
117052 C546325 M Manual -1 2011-03-11 10:15:00 1687.17 14911.0 EIRE
In [24]:
transaction_table[(transaction_table['StockCode'].map(str).map(len) <= 4) |
                  (transaction_table['StockCode'].map(str).map(len) >= 7)].head()
Out[24]:
InvoiceNo StockCode Description Quantity InvoiceDate UnitPrice CustomerID Country
45 536370 POST POSTAGE 3 2010-12-01 08:45:00 18.00 12583.0 France
132 536381 15056BL EDWARDIAN PARASOL BLACK 2 2010-12-01 09:41:00 5.95 15311.0 United Kingdom
141 C536379 D Discount -1 2010-12-01 09:41:00 27.50 14527.0 United Kingdom
281 536396 15056BL EDWARDIAN PARASOL BLACK 6 2010-12-01 10:51:00 4.95 17850.0 United Kingdom
386 536403 POST POSTAGE 1 2010-12-01 11:27:00 15.00 12791.0 Netherlands

loc、ilocによるインデックス参照

これまでにも何度か登場しましたが、データの選択を行う場合インデックスのラベルを指定するのか、位置を指定するのかは可能な限り明示する方が良いです。(特にラベルが数値である場合)

インデックスラベルによる参照ではlocフィールド、インデックス位置による参照ではilocフィールドを使います。これらを使うと、NumPy配列のように軸を指定して、データフレームから行や列の一部分を選択することが出来ます。

また特定の1つの値を抽出したい場合は、より明示的にatフィールド、iatフィールドを使うことができます。それぞれの用法を簡単な例で確認しておきましょう。

In [25]:
transaction_table.loc[:, 'StockCode': 'UnitPrice']
Out[25]:
StockCode Description Quantity InvoiceDate UnitPrice
0 85123A WHITE HANGING HEART T-LIGHT HOLDER 6 2010-12-01 08:26:00 2.55
1 71053 WHITE METAL LANTERN 6 2010-12-01 08:26:00 3.39
2 84406B CREAM CUPID HEARTS COAT HANGER 8 2010-12-01 08:26:00 2.75
3 84029G KNITTED UNION FLAG HOT WATER BOTTLE 6 2010-12-01 08:26:00 3.39
4 84029E RED WOOLLY HOTTIE WHITE HEART. 6 2010-12-01 08:26:00 3.39
5 22752 SET 7 BABUSHKA NESTING BOXES 2 2010-12-01 08:26:00 7.65
6 21730 GLASS STAR FROSTED T-LIGHT HOLDER 6 2010-12-01 08:26:00 4.25
7 22633 HAND WARMER UNION JACK 6 2010-12-01 08:28:00 1.85
8 22632 HAND WARMER RED POLKA DOT 6 2010-12-01 08:28:00 1.85
9 84879 ASSORTED COLOUR BIRD ORNAMENT 32 2010-12-01 08:34:00 1.69
10 22745 POPPY’S PLAYHOUSE BEDROOM 6 2010-12-01 08:34:00 2.10
11 22748 POPPY’S PLAYHOUSE KITCHEN 6 2010-12-01 08:34:00 2.10
12 22749 FELTCRAFT PRINCESS CHARLOTTE DOLL 8 2010-12-01 08:34:00 3.75
13 22310 IVORY KNITTED MUG COSY 6 2010-12-01 08:34:00 1.65
14 84969 BOX OF 6 ASSORTED COLOUR TEASPOONS 6 2010-12-01 08:34:00 4.25
15 22623 BOX OF VINTAGE JIGSAW BLOCKS 3 2010-12-01 08:34:00 4.95
16 22622 BOX OF VINTAGE ALPHABET BLOCKS 2 2010-12-01 08:34:00 9.95
17 21754 HOME BUILDING BLOCK WORD 3 2010-12-01 08:34:00 5.95
18 21755 LOVE BUILDING BLOCK WORD 3 2010-12-01 08:34:00 5.95
19 21777 RECIPE BOX WITH METAL HEART 4 2010-12-01 08:34:00 7.95
20 48187 DOORMAT NEW ENGLAND 4 2010-12-01 08:34:00 7.95
21 22960 JAM MAKING SET WITH JARS 6 2010-12-01 08:34:00 4.25
22 22913 RED COAT RACK PARIS FASHION 3 2010-12-01 08:34:00 4.95
23 22912 YELLOW COAT RACK PARIS FASHION 3 2010-12-01 08:34:00 4.95
24 22914 BLUE COAT RACK PARIS FASHION 3 2010-12-01 08:34:00 4.95
25 21756 BATH BUILDING BLOCK WORD 3 2010-12-01 08:35:00 5.95
26 22728 ALARM CLOCK BAKELIKE PINK 24 2010-12-01 08:45:00 3.75
27 22727 ALARM CLOCK BAKELIKE RED 24 2010-12-01 08:45:00 3.75
28 22726 ALARM CLOCK BAKELIKE GREEN 12 2010-12-01 08:45:00 3.75
29 21724 PANDA AND BUNNIES STICKER SHEET 12 2010-12-01 08:45:00 0.85
541879 22726 ALARM CLOCK BAKELIKE GREEN 8 2011-12-09 12:31:00 3.75
541880 22727 ALARM CLOCK BAKELIKE RED 4 2011-12-09 12:31:00 3.75
541881 16016 LARGE CHINESE STYLE SCISSOR 10 2011-12-09 12:31:00 0.85
541882 21916 SET 12 RETRO WHITE CHALK STICKS 24 2011-12-09 12:31:00 0.42
541883 84692 BOX OF 24 COCKTAIL PARASOLS 25 2011-12-09 12:31:00 0.42
541884 84946 ANTIQUE SILVER T-LIGHT GLASS 12 2011-12-09 12:31:00 1.25
541885 21684 SMALL MEDINA STAMPED METAL BOWL 12 2011-12-09 12:31:00 0.85
541886 22398 MAGNETS PACK OF 4 SWALLOWS 12 2011-12-09 12:31:00 0.39
541887 23328 SET 6 SCHOOL MILK BOTTLES IN CRATE 4 2011-12-09 12:31:00 3.75
541888 23145 ZINC T-LIGHT HOLDER STAR LARGE 12 2011-12-09 12:31:00 0.95
541889 22466 FAIRY TALE COTTAGE NIGHT LIGHT 12 2011-12-09 12:31:00 1.95
541890 22061 LARGE CAKE STAND HANGING STRAWBERY 8 2011-12-09 12:49:00 2.95
541891 23275 SET OF 3 HANGING OWLS OLLIE BEAK 24 2011-12-09 12:49:00 1.25
541892 21217 RED RETROSPOT ROUND CAKE TINS 24 2011-12-09 12:49:00 8.95
541893 20685 DOORMAT RED RETROSPOT 10 2011-12-09 12:49:00 7.08
541894 22631 CIRCUS PARADE LUNCH BOX 12 2011-12-09 12:50:00 1.95
541895 22556 PLASTERS IN TIN CIRCUS PARADE 12 2011-12-09 12:50:00 1.65
541896 22555 PLASTERS IN TIN STRONGMAN 12 2011-12-09 12:50:00 1.65
541897 22728 ALARM CLOCK BAKELIKE PINK 4 2011-12-09 12:50:00 3.75
541898 22727 ALARM CLOCK BAKELIKE RED 4 2011-12-09 12:50:00 3.75
541899 22726 ALARM CLOCK BAKELIKE GREEN 4 2011-12-09 12:50:00 3.75
541900 22730 ALARM CLOCK BAKELIKE IVORY 4 2011-12-09 12:50:00 3.75
541901 22367 CHILDRENS APRON SPACEBOY DESIGN 8 2011-12-09 12:50:00 1.95
541902 22629 SPACEBOY LUNCH BOX 12 2011-12-09 12:50:00 1.95
541903 23256 CHILDRENS CUTLERY SPACEBOY 4 2011-12-09 12:50:00 4.15
541904 22613 PACK OF 20 SPACEBOY NAPKINS 12 2011-12-09 12:50:00 0.85
541905 22899 CHILDREN’S APRON DOLLY GIRL 6 2011-12-09 12:50:00 2.10
541906 23254 CHILDRENS CUTLERY DOLLY GIRL 4 2011-12-09 12:50:00 4.15
541907 23255 CHILDRENS CUTLERY CIRCUS PARADE 4 2011-12-09 12:50:00 4.15
541908 22138 BAKING SET 9 PIECE RETROSPOT 3 2011-12-09 12:50:00 4.95

541909 rows × 5 columns

In [26]:
transaction_table.iloc[:5, 1:6]
Out[26]:
StockCode Description Quantity InvoiceDate UnitPrice
0 85123A WHITE HANGING HEART T-LIGHT HOLDER 6 2010-12-01 08:26:00 2.55
1 71053 WHITE METAL LANTERN 6 2010-12-01 08:26:00 3.39
2 84406B CREAM CUPID HEARTS COAT HANGER 8 2010-12-01 08:26:00 2.75
3 84029G KNITTED UNION FLAG HOT WATER BOTTLE 6 2010-12-01 08:26:00 3.39
4 84029E RED WOOLLY HOTTIE WHITE HEART. 6 2010-12-01 08:26:00 3.39
In [27]:
transaction_table.at[0, 'StockCode']
Out[27]:
'85123A'
In [28]:
transaction_table.iat[-1, -1]
Out[28]:
'France'

インデックス位置の指定では、PythonのリストやNumPy配列同様、マイナスを使って終端からの位置を指定することが可能です。

本格的に学びたい人のためのリソース

Pandasを本格的に学びたいのであれば、以下の理由から「Pythonによるデータ分析入門」がイチオシです。

基礎力を身に着けたら、出来る限り早く実データによる様々な分析に羽ばたきましょう!

おすすめ理由

  • Pandas開発者が著者ということもあり、内容が正確である
  • 網羅性が高い
  • JupyterNotebookや前提となるPythonやNumPyの範囲もカバーしており、初心者でも十分読める
  • matplotlibやPandasの可視化メソッドによる可視化をカバーしている
  • 後半の章で、いくつかのデータ分析の実例を学べる