Pandas 練習ノート
"Getting started" のページからリンクされている "Intro to pandas" と "10 minutes to pandas" について,API リファレンスを参照しながら作成しました.
API リファレンスには,例えば関数やメソッドの記述にキーワード引数が詳細に紹介されています.
クラス,関数,引数などの数が多くて憶えきれん,が,API リファレンスを読めれば何とかなるかも,という期待によります.
Pandas には NumPy API が使われています.私は,Pandas を学ぶ前に少しだけ NumPy を学んでおきました(NumPy 練習ノート).
インフォメーション
オンラインドキュメント
このページでは,pandas documentation — pandas 2.2.1 documentation 内に見つかる,下記ドキュメントを中心に勉強します.
Getting started:Intro to pandas でイメージを把握します.
10 minutes to pandas:"User Guide" の 1 ページです.この冒頭部分を中心に学びます."Getting Started" からは "Tutorials" としてリンクされています.
API reference:API リファレンスを確認しつつ "10 minutes to pandas" のコードを勉強します
目次(ページ内リンク)
イントロダクション
Object creation:オブジェクトの作成
Viewing data:データの表示
Selection:データの選択
イントロダクション
Pandas の機能
"Getting Started" 内に,"Intro to pandas" というセクションがあり,Pandas の主な(?)機能が紹介されています.
これから練習を始めるに際して(Pandas を使ったことがない状態で)まとめてみました.
- Pandas は.DataFrame という表形式のデータテーブルを作成して操作するツールです.スプレッドシートやデータベースなど,表形式のデータとの親和性が高そうです
- csv,excel,sql,json,parquet などがデータソースとして利用できます(a)
- DataFrame の特定の行あるいは列を選択することができます.さらに,条件に基づいて必要なデータをスライス,選択,抽出するメソッドがあります
- 他の列の既存のデータに基づいて DataFrame に列を追加することも可能です
- データテーブルのレイアウトを変更するために,melt() や pivot() という関数が実装されています
- データベースのような結合/マージ操作が提供されているため,複数のテーブルを列方向と行方向の両方で連結できます
- 日付,時刻,および時間インデックス付きデータを操作するためのツールセットを備えています
- 平均,中央値,最小,最大,カウントなどの基本的な統計量は,データセット全体あるいはカテゴリごとにグループ化して(b)計算することができます
- pandas は,Matplotlib の機能を使用して,データをプロットします.散布図,棒グラフ,箱ひげ図などを選択できます
- テキスト データをクリーンアップし,そこから有用な情報を抽出するための関数があります
(a):データのインポートは,プレフィックス read_* が付いた関数を使います. データを保存するには,to_* メソッドを使います."Intro to pandas" のこの段落では,関数 function という表現と メソッド method という表現が併用されています.
(b):"split-apply-combine" アプローチというそうです.
データ構造を表現するクラス
Pandas では,データを扱うためのクラスが 2 個用意されています:
"10 minutes to pandas" ではユーザーガイドや API リファレンスへのリンクが張られています.以下では,これらを参照しつつコーディングの練習をします.
ここでの目標は,API リファレンスを参照しつつ練習できるようになることなので,"10 minutes to pandas" ごく一部のコードを練習しています.
Object creation:オブジェクトの作成
ライブラリのインポート
ライブラリ numpy および pandas は通常,このソースコードのようにインクルードします.
NumPy のページに記されている説明を改変すれば,「広く採用されている慣例で,Pandas を使ったコードを読みやすくするために,インポートする名前を pd と短くします」とか,「常に import pandas as pd を使用することをお勧めします」となるのでしょう.
import numpy as np
import pandas as pd
Series
下は,"10 minutes to pandas" の最初の作成例をコードに書き換えたものです.
Serien のコンストラクタ引数として値のリスト([1, 3…])を渡しています.他の引数は省略しているのでデフォルト値が使われます.
np.nan は非数(Not a Number)ですが,NumPy を使っています.
import numpy as np
import pandas as pd
s = pd.Series([1, 3, 5, np.nan, 6, 8])
print(s)
Series のクラス宣言を API リファレンスで見ると,
class pandas.Series(data=None, index=None, dtype=None, name=None, copy=None, fastpath=_NoDefault.no_default)
コンストラクタ引数はそれぞれ,
data : array-like, Iterable, dict, or scalar value
Series インスタンスに保管される配列やリストなどのデータ.API リファレンスには,"array-like, Iterable, dict, or scalar value" と書いてあります.
index : array-like or Index (1d)
デフォルト 値は RangeIndex (0, 1, 2, …, n)です .index が省略された場合,data が辞書型であれば,キーが index となります.
dtype : str, numpy.dtype, or ExtensionDtype, optional
データ型です指定しない場合は data から推測されます.Series の要素のデータ型は,NumPy の dtype を利用しています.
name : Hashable, default None
Series の名前(現時点では解りませんが,Series を束ねて DataFrame を作成した際に列名として使うとかでしょうか).
copy : bool, default False
data のコピーを作成するか参照とするかを設定します.デフォルト値は false.すなわち,元データの参照が格納されます.
fastpath : 説明は記述されていません
現時点では使い方が解りません.ソースコードを見ると bool 値のようです.
下が実行結果です.data,index,および dtype が出力されました.
0 1.0 1 3.0 2 5.0 3 NaN 4 6.0 5 8.0 dtype: float64
DataFrame
"10 minutes to pandas" には DataFrame の作成例がいくつか紹介されているのですが,最初の例を参考にしてコーディングしてみます.
import numpy as np
import pandas as pd
dates = pd.date_range("20130101", periods=6)
df = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=list("ABCD"))
print(df)
DataFrame のクラス宣言を API リファレンスで見ると,
class pandas.DataFrame(data=None, index=None, columns=None, dtype=None, copy=None)
コンストラクタ引数は,以下の意味です.
data : ndarray (structured or homogeneous), Iterable, dict, or DataFrame
dict には,系列,配列,定数,データ・クラス,リストのようなオブジェクトを含めることができるそうです.
あと,列の整列規則が記されています.
index : Index or array-like
生成する DataFrame に使用するインデックス.デフォルトは RangeIndex となります.
columns : Index or array-like
データに列ラベルが含まれていない場合に使われるラベルです.デフォルトは RangeIndex(0, 1, 2, ..., n).
データに列ラベルが含まれている場合は,代わりにそれで列選択を行います.
dtype : dtype, default None
データ型(Data type to force と書いてあります).単一のデータ型のみが可能です.省略した場合は data から推測されるようです.
copy : bool or None, default None
data をコピーするか参照にするか.
data が dict 型の場合,デフォルトの None は copy=True と動作します.data が DataFrame 型の場合,デフォルトの None は copy=False と動作します.
下は,実行したときの出力の一例です.
A B C D 2013-01-01 1.136817 0.193710 -0.132566 2.237783 2013-01-02 0.068851 -0.187624 -0.774221 1.061339 2013-01-03 0.266911 -0.684776 -2.650970 0.921205 2013-01-04 0.653107 -0.608141 -0.259438 -0.822131 2013-01-05 0.980141 1.926887 -1.075509 -0.864783 2013-01-06 0.429613 1.478922 -2.663787 -0.106529
Viewing data:データの表示
"10 minutes to pandas" では,以下のメソッドが紹介されています.各メソッドは API リファレンスにリンクを張って,引数を明瞭にしました.
- DataFrame.head(n=5):DataFrame の先頭から n 行を返します.デフォルトは 5 行です
- DataFrame.tail(n=5):DataFrame の先頭から n 行を返します.デフォルトは 5 行です
- DataFrame.index:これは () なしの関数です.戻り値は DataFrame のインデックスラベルです
- DataFrame.columns:API リファレンスには,単に DataFrame のカラムラベルと書いてあります.こちらは関数ではないのかも
- DataFrame.describe(percentiles=None, include=None, exclude=None):統計量の要約を記した Series または DataFrame を返します
- DataFrame.sort_index(*, axis=0, level=None, ascending=True, inplace=False, kind='quicksort', na_position='last', sort_remaining=True, ignore_index=False, key=None)
- DataFrame.sort_values(by, *, axis=0, ascending=True, inplace=False, kind='quicksort', na_position='last', ignore_index=False, key=None)
DataFrame.describe() のサンプルコード
API リファレンスのサンプルコードを改変して紹介します.
デフォルトでは,'numeric' データのみ,25, 50, 75 パーセンタイルで区分けしたデータが返されます.
引数を設定することにより,これらを変更することができます.
import pandas as pd
df = pd.DataFrame({'categorical': pd.Categorical(['d', 'e', 'f']),
'numeric': [1, 2, 3],
'object': ['a', 'b', 'c'] })
print(df.describe(percentiles=[0.25, 0.5, 0.75])) #パーセンタイルの指定はリストを渡す.これはデフォルト値なので省略しても同じ
print()
print(df.describe(percentiles=[0.2, 0.4, 0.6, 0.8], include='all')) #include のオプションで 'numeric' 以外のデータも表示
実行結果を下に示します.
上半分は df.describe() のデフォルトの戻り値を出力したもの,した半分が df.describe() の戻り値を変更したものです.
numeric count 3.0 mean 2.0 std 1.0 min 1.0 25% 1.5 50% 2.0 75% 2.5 max 3.0 categorical numeric object count 3 3.0 3 unique 3 NaN 3 top d NaN a freq 1 NaN 1 mean NaN 2.0 NaN std NaN 1.0 NaN min NaN 1.0 NaN 20% NaN 1.4 NaN 40% NaN 1.8 NaN 50% NaN 2.0 NaN 60% NaN 2.2 NaN 80% NaN 2.6 NaN max NaN 3.0 NaN
DataFrame.sort_values() のサンプルコード
ソートには sort_index() と sort_values() があります.ここでは,後者を練習してみます.
まず,引数を整理します.
- by(str or list of str):ソートに使う列名またはインデックスラベルを指定します
- axis(“{0 or ‘index’, 1 or ‘columns’}”, default 0):axis=0 あるいは axis='index' なら指定したインデックスラベルの大小関係に従って,axis=1 あるいは axis='column' なら指定した列の大小関係に従ってソートします
- ascending(bool or list of bool, default True):昇順か降順か.デフォルトは昇順
- inplace(bool, default False):True にすると In-place アルゴリズムを使います.コピーを作るのではなく,オブジェクト自体がソートされるので,戻り値は None です
- kind({‘quicksort’, ‘mergesort’, ‘heapsort’, ‘stable’}, default ‘quicksort’):ソートアルゴリズムです.デフォルトはクイックソート
- na_position({‘first’, ‘last’}, default ‘last’):非数データ NaN をどこに置くかを指定します.デフォルトは末尾
- ignore_index(bool, default False):Ture にすると,インデックスラベルが 0, …, n-1 となります
- key(callable, optional):サンプルコードを見ると,ラムダ関数でソートの順序を設定しています
DataFrame.sort_values() のサンプルコード
種々の引数オプションを付けてコードを作成してみました.
適宜,コメントアウト,コメントインしてください.
import pandas as pd
import numpy as np
df = pd.DataFrame(
data={
'col2': [4, 5, 6, 1, 2, 3],
'col1': [6, 5, 4, 3, 2, 1],
'col3': [2, 4, 6, 1, 3, np.NaN]},
index=['A', 'B', 'C', 'D', 'E', 'F']
)
print(df)
print()
#これらは DataFrame が戻り値
sorted = df.sort_values(by='col1')
#sorted = df.sort_values(by='col1', axis=0)
#sorted = df.sort_values(by='A', axis=1)
#sorted = df.sort_values(by=['col1', 'col2'])
#sorted = df.sort_values(by='col1', ascending=False)
#sorted = df.sort_values(by='col1', ignore_index=True)
#sorted = df.sort_values(by='col3', na_position='first')
print(sorted)
#これは戻り値が None
#df.sort_values(by='col1', inplace=True)
#print(df)
Selection:データの選択
"10 minutes to pandas" のこのセクションの冒頭で,Python / NumPy 構文は直感的で対話型の作業に便利としつつ,コードを作成する場合には Pandas のメソッドが推奨されています.
ここでは,それらのメソッドを試してみます.
API リファレンスでは以下のように宣言されています.リンク先は API リファレンスです.API リファレンスの宣言では,引数が書かれていませんが,サンプルコードに引数の実例があります
サンプルコード
API リファレンスの at および iat に記されているサンプルコードを改変して紹介します.
import pandas as pd
df = pd.DataFrame(
[[0, 2, 3], [0, 4, 1], [10, 20, 30]],
index=[4, 5, 6],
columns=['A', 'B', 'C'])
print(df)
print()
#at の利用例
print("df.at[4, 'B'] =", df.at[4, 'B'])
df.at[4, 'B'] = 10
print("df.at[4, 'B'] =", df.at[4, 'B'])
#iat の利用例
print("df.iat[1, 2] =", df.iat[1, 2])
df.iat[1, 2] = 10
print("df.iat[1, 2] =", df.iat[1, 2])
print("df.loc[5].at['B']", df.loc[5].at['B']) #loc + at
print("df.iloc[0].iat[1]", df.iloc[0].iat[1]) #iloc + iat
API リファレンスを参照しつつ "10 minutes to pandas" を読み進めることが可能であると示せたと思います.
"10 minutes to pandas" の記述は以下のように続きますが,今バージョンでは一旦終了します.
少なくとも,Debian GNU/Linux のメジャーバージョンアップ時に,構成の見直しをするつもりです.
- selection の残り
- missing_data
- operations
- merge
- grouping
- reshaping
- time_series
- categoricals
- plotting
- Importing_exporting
- gotchas
参考書の検索
- Amazon の「コンピュータ・IT」本カテゴリーでの,「python」での検索結果です
- Amazon の「コンピュータ・IT」本カテゴリーでの,「Pandas」での検索結果です