[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を読み込んだりする。

pandas.read_csv(filename, sep=',') -> pandas.DataFrame

CSVファイルを読み込んでDataFrameを返す。あらかじめopen関数を使ってファイルを開いておく必要はない。タブ区切りの場合はsep='/t'と指定する.

pandas.DataFrame.to_csv(filename) -> Union[str, NoneType]

DataFrameをCSVファイルに書き込む。こちらもあらかじめファイルを開いておく必要はない。デフォルトではカンマ区切り。ちなみに、Excelはタブ区切りのCSVファイルを一発で読み込めないため、Excelを使う予定ならタブ区切りよりカンマ区切りのCSVファイルの方が便利。ファイル名を指定しない場合は、ファイルに書き込まれるはずだった文字列が戻り値となる。

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()を使ってちゃんとコピーを受け取るようにすれば、警告はでなくなる。