[Python][Pandas] Pandasの基本用法まとめ
環境:Windows10 + Anaconda 4.8.1 + Python 3.7 + Pandas 1.0.5
目次
はじめに
PythonにはPandasというデータ分析用のライブラリがある。使いこなせれば、CSVファイルなど表形式のデータからいろいろな情報を引き出すことができる。
一方で、Pythonの基本文法とは異なる、ライブラリ特有の文法に関する知識が必要なため、最初のハードルは決して低くないように思う。Pandasの文法は、Pythonの基本文法と違うだけでなく、Numpyとも違い、Rとも違うと感じる。ゆえに直観的に理解しづらい。
そこでこのページでは、Pandasの基本的な用法をまとめることにする。自分の勉強も兼ねている部分があるので、足りない部分やまだ分からない部分もあるが、随時書き足していけたらと思う。
準備
インストール
Anaconda環境の場合は
conda install pandas
としてインストールする。
バージョン
大きく二つのバージョンが存在する。
- ver0.25系(記事執筆時点では0.25.3が最新)
- ver1.0系(記事執筆時点では1.0.5が最新)
pandas.pydata.org
pandas.pydata.org
バージョン1.0.0がリリースされたのは2020年1月29日と比較的最近のことであり(記事執筆時点においては)、ver0.25系を用いているプログラムもまだまだ多いと思われる。ver1.0では一部の機能が削除されており、公式ドキュメントではver0.25からver1.0に更新する前にソースコードが警告なしで作動するか確認するようにとアナウンスしている*1。
新しくインストールする場合は、ver1.0をインストールすればよい。すでにインストール済みの場合は、更新する前に確認することをおすすめする(仮想環境を新たに作成するのも一つの手)。
インポート
import pandas as pd
とするのが一般的。
サンプルデータ
Pandasの機能を試すために、サンプルデータを使いたいときがある。しかし調べた限りでは、Pandasにはサンプルデータは含まれていなかった。そこで代わりにseabornライブラリから読み込むことにする。
seaborn.load_dataset('iris') # --> pandas.DataFrame
ここではseabornライブラリからiris(アヤメ)のデータを読み込んでいる。seabornライブラリから読み込んでも、pandasのDataFrameで返してくれる。
Pandasの型
Pandasには多数の型があり、把握するだけでも一苦労である。Pandasの型については次のページが詳しい。
https://pbpython.com/pandas_dtypes.html
note.nkmk.me
ここでは使用頻度の高そうな型にしぼって取り上げる。
- DataFrame:データフレーム。データセットは主にこの型で処理される。
- Series:シーケンス。Seriesが集まったものがDataFrameである。
- 要素:シーケンスの要素にはいろいろな型がある。主なものを以下に列挙する。
- int64:整数
- float64:倍精度浮動小数点
- bool:ブール値
- object:文字列または型の混合
- datetime64:日付を表す
- timedelta:時間差を表す
- category:カテゴリカルなデータを表す
いま扱っている変数はDataFrameかSeriesか要素か、要素であれば何の型か、を意識しながらプログラムを書くことになる。
データフレームの作成
いくつかの方法があるが、最も簡単な方法を一つ示す。
pandas.DataFrame( data, columns=['column0', 'column1', 'column2'], dtype={'column0': 'float', 'column1': 'int', 'column2': 'object'} )
作成したリスト内リスト(行列)を、pandasのDataFrameに変換する。列名をcolumns引数で指定し、各列の型をdtype引数に辞書で指定する(オプション)。
CSVファイルの読み込み・書き出し
Pandasでデータを処理するにあたって、CSVファイルは最も基本となるファイルの一つ。DataFrameをCSVで保存したり、CSVからDataFrameを読み込んだりする。
Seriesの基本操作
DataFrameから一列取り出すとSeriesになる。まずはSeriesから要素を取り出す方法を示す。
pandas.Series.at[label]など
pandas.Series.at[label] # -> 要素 pandas.Series.iat[n] # -> 要素 pandas.Series.loc[label1:label2] # -> pandas.Series pandas.Series.iloc[n1:n2] # -> pandas.Series
以上の四つの方法では、「取り出すもの」と「要素の指定方法」に違いがある。
取り出すもの | 要素の指定方法 | |
---|---|---|
at |
単独の要素 | ラベル(インデックス) |
iat |
単独の要素 | 整数 |
loc |
複数の要素 | ラベル(インデックス) |
iloc |
複数の要素 | 整数 |
ラベルを使って指定するか整数を使って指定するかという違いはあるが、おそらく多くのSeriesではラベルが整数であるため(つまりlabelが整数)、どちらを使っても同じにはなる。ただし、iloc
では最後の値(n2
)を含まないのに対し、loc
では最後の値(label2
)を含むことに注意する必要がある。
とは言え、上記四つの方法を目的に応じて使い分けるのはやや面倒なので、巨大なデータでなければnumpy.ndarrayやlistに変換してから要素にアクセスするの方が、間違いがなくて良いと思う。
numpy.ndarrayやlistに変換する方法を示す。
pandas.Series.values -> numpy.ndarray
Seriesをnumpy.ndarrayに変換して返す。
pandas.Series.to_list() -> [Any, ...]
Seriesを標準Pythonのリストに変換して返す。values
はインスタンス変数だが、to_list
はメソッドであることに注意。
pandas.Series.index.values -> numpy.ndarray
Seriesのラベル(インデックス)を返す。たいていは[0, 1, 2, ...]という整数のシーケンス。最後にvaluesを着けない場合は、イテラブルなpandas.RangeIndexというオブジェクトが返される。
Seriesの長さや要素の型は、インスタンス変数に入っている。
pandas.Series.size -> int
Seriesが持つ要素の数を返す。配列の長さと同じ。
pandas.Series.dtype -> numpy.dtype
要素の型を返す.
DataFrameの基本操作
pandas.DataFrame.at[label_row, label_col]など
pandas.DataFrame.at[label_row, label_col] # -> 要素 pandas.DataFrame.iat[n_row, n_col] # -> 要素 pandas.DataFrame.loc[label1_row:label2_row, label1_col:label2_col] # -> pandas.DataFrame pandas.DataFrame.iloc[n1_row:n2_row, n1_col:n2_col] # -> pandas.DataFrame
Seriesの場合と同様に、atとiatは単独の要素を取得するのに対し、locとilocは複数の要素(この場合はDataFrame)を取得する。atとlocはラベル(インデックス)を用いて、iatとilocは整数を用いて位置を指定する。
pandas.DataFrame.head(n=5) -> pandas.DataFrame
データフレームの先頭n行を返す(デフォルトでは5行)。printして中身を確認するといった用途に。
pandas.DataFrame.columns.values -> numpy.ndarray
列名をリストで取得する。
pandas.DataFrame.index.values -> numpy.ndarray
行名をリストで取得する。
pandas.DataFrame['column'] -> pandas.Series
列名columnのSeriesを取得する。
イテレーション
pandas.DataFrame.iterrows() -> Iterable
Indexとrowのtupleを返すイテラブル。rowはpandas.Seriesに変換されている。データにはrow[‘column’]という形でアクセス可能。ただしこのメソッドは遅いので、可能ならば次のメソッドを使う方が良い。
pandas.DataFrame.itertuples() -> Iterable
一行ずつ返すイテラブル。行はPandasという名前のnamedtupleに変換されている。データにはrow[0]またはrow.columnといった形でアクセス可能。
Seriesをそのまま使う
Seriesはそれ自体イテラブルになっている。DataFrame全体ではなく、特定のcolumnだけが必要ならば、columnを指定してSeriesで回した方が早い。
速度比較
イテレーションの処理速度比較については次のページが詳しい.
note.nkmk.me
条件抽出
pandas.Series.isin(values) -> pandas.Series
Seriesの各要素がvalueに指定した集合またはシーケンスに含まれるかどうかを判定し、bool値のSeriesを返す。
要素カウント
pandas.Series.unique() -> numpy.ndarray
Seriesに含まれる要素のシーケンスを返す。値の重複はなく、Python組み込みの集合のようなもの。
pandas.Series.value_counts() -> pandas.Series
Seriesに含まれる要素とその出現回数をSeriesで返す。indexに要素の値が、valueに要素の出現回数が入る。Seriesだと扱いにくいという場合は、次のメソッドが便利。
pandas.Series.value_counts().to_dict() -> Dict[Any, int]
Seriesに含まれる要素とその出現回数を辞書で返す。
警告
SettingWithCopyWarning
条件やスライスで抽出したDataFrameは、コピーではなく参照を返すことがある。その参照に対して代入など中身を変更する処理を行うとこの警告が発生する。参照ではなく値を返してほしい場面では、pandas.DataFrame.copy()
を使ってちゃんとコピーを受け取るようにすれば、警告はでなくなる。