Pandas 練習ノート
Pandas のオンラインドキュメントに,"Getting started" というページがあります.そのなかに "Intro to pandas" というセクションがあり,Pandas の機能が紹介されています.
- Pandas は.DataFrame という表形式のデータテーブルを作成して操作するツールです
- csv,excel,sql,json,parquet などがデータソースとして利用できます
- DataFrame の特定の行あるいは列を選択することができます.さらに,条件に基づいて必要なデータをスライス,選択,抽出するメソッドがあります
- 他の列の既存のデータに基づいて DataFrame に列を追加することも可能です
- データテーブルのレイアウトを変更するために,melt() や pivot() というメソッドが実装されています
- データベースのような結合/マージ操作が提供されているため,複数のテーブルを列方向と行方向の両方で連結できます
- 日付,時刻,および時間インデックス付きデータを操作するためのツールセットを備えています
- 平均,中央値,最小,最大,カウントなどの基本的な統計量は,データセット全体あるいはカテゴリごとにグループ化して計算することができます
- pandas は,Matplotlib の機能を使用して,データをプロットします.散布図,棒グラフ,箱ひげ図などを選択できます
- テキスト データをクリーンアップし,そこから有用な情報を抽出するためのメソッドがあります
このページでは,"Getting started" のページからリンクされている "Intro to pandas" と "10 minutes to pandas" を,API リファレンスを参照しながら少しだけ HTML に記してみます.
Pandas には NumPy API が使われています.私は,Pandas を学ぶ前に少しだけ NumPy を学んでおきました(NumPy 練習ノート).
インフォメーション
オンラインドキュメント
- pandas documentation公式オンラインドキュメント
- Getting started:pandas documentation 内のページ.このなかに "Intro to pandas" というセクションがあって,基本的な情報が得られます
- 10 minutes to pandas:pandas documentation 内にある "User Guide" のページ."Getting Started" からは "Tutorials" のひとつとしてリンクされています
- API reference:このページでは,API リファレンスを確認しつつ "10 minutes to pandas" のコードを勉強します
- Essentially basics functionality section:pandas documentation 内にある "User Guide" のページ
Debian パッケージ
このページは,Debian GNU/Linux バージョン 13 "trixie" で作成しました.
インストールしている主なパッケージを示します.
| パッケージ名(バージョン) | 注 |
| python3 (3.13.5) | 対話式の高レベルオブジェクト指向言語(このページ改定開始前にインストール済みでした) |
| python3-pandas (2.2.3) | データ分析をするためのパッケージ.リレーショナルデータを扱う DataFrame クラスと ラベル付きデータを扱うための Seried クラスがあります |
| python-pandas-doc (2.2.3) | HTML ドキュメントが /usr/share/doc/python-pandas-doc/html/ 以下にインストールされました |
目次(ページ内リンク)
目次として,"10 minutes to pandas" のパラグラフのタイトルと,このページのセクションへのリンクとを対応付けてみました.
- Basic data structures in pandas:基本データ構造
- Object creation:Series のインスタンス化,DataFrame のインスタンス化
- Viewing data:データの表示
- selectio:データフレームでの選択
- missing_data
- operations
- merge
- grouping
- reshaping
- time_series
- categoricals
- plotting
- Importing_exporting
- gotchas
Pandas の基本データ構造
"Basic data structures in pandas" を読むと,Pandas には,データ処理をおこなうためのクラスが 2 個あると書いてあります.
(書いてあって,API リファレンスへのリンクが張ってあるだけです)
DataFrame の API リファレンスを眺める
上のリンクから,より頻用するであろう DataFrame の API リファレンスのトップページに移動すると,以下の構成となっています.
コンストラクタでインスタンス化の方法を学んで,サンプルコードで簡単な使い方を理解して,細かいことはアトリビュートやメソッドを見れば良さそうです.
- クラス宣言とコンストラクタ引数
- 対話形式でのサンプルコード
- アトリビュート
- メソッド
アトリビュートとは,別の言語でいうと,公開メンバ変数とかプロパティに該当するのでしょうか.すなわち, "." 演算子でアクセスでき,かつ () でパラメータを渡さないオブジェクトです.
イメージするために最初の 5 個を列挙してみます.
- T:転置.調べないと判りませんが,コンストラクタで作成されるのでしょうか?
- at:格納されている値.[] 演算子で行と列を指定します
- attrs:Dictionary of global attributes of this dataset.今の私にはイメージしにくいので,今後の課題とします
- axes:データフレームの軸を表すリスト
- columns:データフレームの列ラベル
Series のインスタンス化
Series は,種々のデータ型を格納する一次元のラベル付き配列です.
このパラグラフでは,"10 minutes to pandas" の最初の例をソースファイルの形に書き換えます.
ライブラリのインポート
ライブラリ numpy および pandas は通常,このソースコードのようにインクルードします.
NumPy のページに記されている説明を改変すれば,「広く採用されている慣例で,Pandas を使ったコードを読みやすくするために,インポートする名前を pd と短くします」とか,「常に import pandas as pd を使用することをお勧めします」となるのでしょう.
import numpy as np
import pandas as pd
ソースコード
下にソースコードを示します.
Series のコンストラクタ引数として値のリスト([1, 3…])を渡しています.他の引数は省略しているのでデフォルト値が使われます.
np.nan は非数(Not a Number)のことですが,NumPy のオブジェクトを使っています.そのため numpy もインポートする必要があります.
ソースコード
ここでは,main.py という名前で保存することにします.
import numpy as np
import pandas as pd
s = pd.Series([1, 3, 5, np.nan, 6, 8])
print(s)
実行してみる
main.py という Python スクリプトを実行するには,端末に,
$ python3 main.py
と入力するのでした.結果,次のように表示されました.
下が実行結果です.インデックス,値,および dtype というものが出力されました.
dtype は Numpy のデータ型です.Pandas ではそれをそのまま使っているようです.
0 1.0 1 3.0 2 5.0 3 NaN 4 6.0 5 8.0 dtype: float64
Series のクラス宣言
API リファレンスで pandas.Seriesを見ると,次のように書いてあります.
class pandas.Series(data=None, index=None, dtype=None, name=None, copy=None, fastpath=<no_default>)
コンストラクタパラメータはそれぞれ,
data : array-like, Iterable, dict, or scalar value
作成される Series インスタンスの元となるデータ.Python のリストなど.
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 値のようです.
API リファレンスの最初の例
ソースファイルの形にすると次のようになります.
第一パラメータ data に辞書型配列を渡しています.この場合,第二パラメーの index は省略しても,data のキーが index になるはずです.
import numpy as np
import pandas as pd
d = {'a': 1, 'b': 2, 'c': 3}
ser = pd.Series(data=d, index=['a', 'b', 'c']) #ser = pd.Series(data=d) でも同じ動作になるはず
print(ser)
実行すると,
a 1 b 2 c 3 dtype: int64
第二パラメーを省略してみたら,期待どおり同じ結果になりました.
DataFrame のインスタンス化
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 df の行ラベルと値は,具体的な値を記述するのではなく,メソッドを使って作成しています.読みにくくなりそうなので,これらのメソッドについては,API リファレンスへのリンクを張るにとどめます.
- 行ラベルは,pandas.date_range() で日付型のインデックスを生成
- 格納する値は,numpy.random.randn() で乱数を発生
実行結果
下は,実行したときの出力の一例です.
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
DataFrame のクラス宣言
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 と動作します.
データの表示
データの表示に関わるメソッドとアトリビュート
以下のメソッドが紹介されています.各メソッドについて,引数を明瞭にしつつ,API リファレンスにリンクを張りました.
- DataFrame.head(n=5):DataFrame の先頭から n 行を返します.デフォルトは 5 行です
- DataFrame.tail(n=5):DataFrame の先頭から n 行を返します.デフォルトは 5 行です
- 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)
データの表示に関わるアトリビュート
"10 minutes to pandas" では,以下のアトリビュートが紹介されています.API リファレンスにリンクを張りました.
- DataFrame.index:DataFrame のインデックスラベル(行ラベル)です
- DataFrame.columns:DataFrame のカラムラベルです
以下で,いくつかサンプルコードを書いてみます.
DataFrame.describe()
describe() メソッドは,デフォルトで,'numeric' データのみ,25, 50, 75 パーセンタイルで区分けしたデータが返されます.
API リファレンスにパラメータを設定するサンプルコードがあるので,それをソースファイルの形に改変して紹介します.
import pandas as pd
import numpy as np
#ここで,'categorical','numeric','object' というのは,単に列名です.
df = pd.DataFrame({'categorical': pd.Categorical(['d', 'e', 'f']),
'numeric': [1, 2, 3],
'object': ['a', 'b', 'c'] })
print(df) #データフレーム全体を出力
#print(df.describe()) #統計諸量を出力.ここでは 'numeric' 列のみ出力されました.値を NaN とするとデータがないものとして計算されました
#print(df.describe(percentiles=[0.25, 0.5, 0.75])) #パーセンタイルを指定して統計諸量を出力.コードのパラメータはデフォルト値
print(df.describe(include='all')) #すべての統計諸量が出力されます.数値に関わる部分は NaN となります
#print(df.describe(include=[np.number])) #'number' 列で,NaN 以外の値が格納された行が出力されました
#print(df.describe(include=['category'])) #'category' 列で,NaN 以外の値が格納された行が出力されました
#print(df.describe(exclude=[np.number])) #'number' 列以外の列で,NaN 以外の値が格納された行が出力されました
#print(df.describe(exclude=[object])) #'number' 列以外の列のすべての行が出力されました
#複数のパラメータを指定する
#print(df.describe(percentiles=[0.2, 0.4, 0.6, 0.8], include='all')) #include のオプションで 'numeric' 以外のデータも表示
実行結果を下に示します.
前半は print(df),後半が print(df.describe(include='all')) の出力です.
categorical numeric object
0 d 1 a
1 e 2 b
2 f 3 c
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
25% NaN 1.5 NaN
50% NaN 2.0 NaN
75% NaN 2.5 NaN
max NaN 3.0 NaN
DataFrame.sort_values() のサンプルコード
ソートには sort_index() と sort_values() があります.ここでは,後者を練習してみます.
もう一度 API リファレンスのメソッド宣言を記すと,
まず,引数を整理します.API リファレンスを読みつつ解釈すると,
- 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') #'col1' 列の大小関係に従って行を入れ替える
#sorted = df.sort_values(by='col1', axis=0) #上と同じ'
#sorted = df.sort_values(by='A', axis=1) #'A' 行の大小関係に従って列を入れ替える
#sorted = df.sort_values(by=['col1', 'col2']) 'col1' の大小関係にしたがって,ただし同値の場合は 'col2' の大小関係に従って行を入れ替える
#sorted = df.sort_values(by='col1', ascending=False) #'col1' 列の大小関係に従って行を入れ替える.ただし,降順
#sorted = df.sort_values(by='col1', ignore_index=True) #index を無視する.出力を見ると,1,2,3,… と行番号が振られていました
#sorted = df.sort_values(by='col3', na_position='first') #'col3' 列の大小関係に従って行を入れ替える.ただし,np.NaN を先頭に置く
print(sorted)
#これは戻り値が None
#df.sort_values(by='col1', inplace=True)
#print(df)
データフレームでの選択
データを選択するアトリビュート
"10 minutes to pandas" のこのセクションの冒頭では,NumPy の構文は直感的で対話型の作業に便利としつつ,コードを作成する場合には Pandas のメソッドを使うことが推奨されています.
以下のアトリビュートが紹介されているのですが,API リファレンスを見ると DataFrame.iloc はバージョン 2.2.0 で廃止されたと記されています.
リンク先は API リファレンスです.
- DataFrame.at:[] 演算子で行ラベルと列ラベルを指定して値にアクセス
- DataFrame.iat:[] 演算子で行番号と列番号を指定して値にアクセス
- DataFrame.loc:Access a group of rows and columns by label(s) or a boolean array.
- DataFrame.iloc:API リファレスによるとンバージョン 2.2.0 で廃止
サンプルコード
ここでは,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()
#loc の利用例
print("df.loc[B] =", df.loc[B])
実行結果
下に実行結果を記します,
A B C
4 0 2 3
5 0 4 1
6 10 20 30
df.at[4, 'B'] = 2
df.at[4, 'B'] = 10
df.iat[1, 2] = 1
df.iat[1, 2] = 10
df.loc[4] = A 0
B 10
C 3
Name: 4, dtype: int64