matplotlib.pyplot – グラフ

グラフの描画

pyplot

figure, axes

グラフの種類

3次元グラフ

tips

 

matplotlib.pyplot – 基本的なグラフの描画方法

概要

pyplotのみを使った基本的なグラフの描画方法。一般的にはmatplotlib.pyplotpltというエイリアスでインポートする。

この例では、pyplotの関数のみを用いて1つのグラフに2つの曲線を描画し、タイトルや軸ラベル、凡例などを追加している。

また、軸目盛の間隔を設定したり、グリッドを描かせたりしている。

実行結果は以下の通り。

ライブラリーのインポート

グラフ描画のためのパッケージ、matplotlob.pyplotpltとしてインポートしている。また、関数描画のためにnumpynpとしてインポート。

描画する関数

ここではpyplotplot()で描画するため、2つの三角関数を準備している。

xの値は共通で、numpy.linspace()で−π~+πの間で等間隔にデフォルトの50個の点を準備。endpoint=Trueで終端の点も含めている。

そのxの値に対して、sin、cosの関数の値をy1y2に保存。numpy.linspace()から得られるxや、それに対してNumpyのユニバーサル関数で計算されるy1y2ndarray

各種設定

タイトルと軸ラベル

pyplot.title()の引数でグラフのタイトル、pyplot.xlabel()pyplot.ylabel()の引数でx軸とy軸のラベルを設定している。

軸の範囲

pyplot.xlim()pyplot.ylim()で、それぞれの軸の下限値と上限値を設定している。x軸については−π~+πとしている。

軸目盛

pyplot.xticks()pyplot.yticks()の引数で、軸目盛に表示する値を設定している。引数は、表示させたい軸の値をリストとして与える。

x軸については−π、−π/2、0、π/2、πの値を直接与え、y軸についてはnumpy.linspace()関数で、-1~+1の間で等間隔な5点(-1、-0.5、0、0.5、1)を計算している。

グリッド(補助線)

グラフの描画エリア内に、軸目盛に対応した細い補助線を描くため、pyplot.grid()の引数をTrueで指定している。

グラフの描画

pyplot.plot()の引数にxy1及びy2を指定してグラフを描いている。2つのplot()関数を書くことで、関数は重なって描かれる。

それぞれのグラフに対してlabel引数を指定していて、それらは凡例表示に使われる。

凡例の表示

pyplot.legend()で凡例を設定している。

凡例にはpyplot.plot()で指定したラベルが使われるため、pyplot.legend()pyplot.plot()の後に書かなければならない。

また、凡例の表示位置をloc引数で指定していて、この場合は左上に凡例が表示される。凡例の位置は、upper/lowerleft/rightをスペースで繋いだ文字列で指定。

グラフの表示

pyplot.show()でグラフを表示させている。

 

Python3 – pandas

概要

pandasはPythonのライブラリで、Rのdata frameのようなデータフレームをDataFrameクラスとして提供している。

その由来はpanel-data-sらしいが、公式ドキュメントにはそういう記述は見当たらない。

DataFrame

 

pandas.DataFrame

情報・内容の取得

データの概観

基本的なパラメーターの取得

DataFrameの生成

要素の操作

列の操作

行の操作

DataFrameで直接行を指定して参照

DataFrameで直接行番号を指定する場合はスライスで指定する。1行取り出す場合でもdf[col:col+1]のようにスライスにしなければならない。

maskによる行の抽出

DataFrameの特定列に対する条件式は、その条件に応じたTrue/Falseを要素とするSeriesオブジェクトを返す。

そのSeriesオブジェクトをDataFrameの引数とすると、Trueに対応する行だけが抽出される。

これをまとめて次のようにも書ける。

抽出結果の特定の列を参照可能。結果はSeriesオブジェクト。

queryによる行の抽出

DataFrameのquery()メソッドでも行を抽出できる。

抽出結果から特定の列を参照可能。結果はSeriesオブジェクト。

行の追加

1行追加する場合

1行追加する場合、locで新たな行インデックスを指定して内容を与える。

複数行追加する場合

複数行(=配列)を追加する場合、その配列をDataFrameオブジェクトとしてからappend()メソッドを使う。ただし単純に追加すると、新たな行・列として拡張されてしまう。

これを回避するためには、追加する行の列名をcolumnsで明示する。ただしこの段階では、追加された行のインデックスが連続していない。

インデックスを連続させるためには、ignore_index=Trueを指定する。

DataFrameの結合

cocatメソッド~縦方向の結合

concat()メソッドは複数のDataFrameを縦に結合した結果を返す。列の構成が同じDataFrameオブジェクトをリスト化して与える。

列数が異なるDataFrameを結合すると、余った要素にはNaNがセットされる。

joinメソッド~横方向の結合

join()メソッドは元のDataFrameに引数のDataFrameを結合した結果を返す。結合は行のインデックスに着目して実行され、インデックスが同じデータは同じ行の列方向に追加される。すなわち、同じ行数で異なる列のDataFrameを結合するのに適している。

破壊的な処理ではなく、元のDataFrameはそのままで新しいDataFrameが生成される。

この例では2つのDataFrameの行が一致しており、列が異なるので、横方向に結合されている。同じ列名が存在する場合はValueErrorとなる。

3つ以上のDataFrameを結合したい場合(引数に2つ以上のDataFrameを指定したい場合)は、それら複数のDataFrameをタプルかリストでまとめて指定する。

合計の計算と合計欄

以下の配列を使う。

sum()メソッドはSeriesオブジェクトを返す。

合計欄としてDataFrameに追加する場合、行/列いずれかの合計を計算して追加し、その上で他方の合計を計算して追加すると、総計まで計算できる。

行の追加はlocプロパティーを通じて、列の追加は列名を指定して行う。

より詳しい合計や率の算出方法はこちら

ソート

 

以下のデータを使用

sort_values()~列名を指定してソート

デフォルトは昇順。元のオブジェクトは変更されず、ソート後のDataFrameオブジェクトが生成されて返される。

ascendingパラメーター

ascending=Falseを指定すると降順でソート。

reset_index()~インデックスの降り直し

ソート後にインデックスを振りなおす場合、reset_index()メソッドを使う。このメソッドも元のオブジェクトを変更しない。

降りなおした後のインデックスで元のインデックスを上書きする場合は、drop=Trueを指定。

複数列によるソート

複数列を指定してソートする場合、ソートの優先順にリストで指定。ascendingパラメーターに同じ要素数のTrue/Falseリストを与えて、列ごとの昇順/降順を指定可能。

axisの方向

各種演算・処理の引数でaxisを設定するときの、行方向・列方向がまぎらわしいので整理。

DataFrameの設定

列のインデックス設定

set_index()メソッドにより、第1引数keysで指定した列をインデックスに設定される。

表示行数・列数の設定

表示行数・列数の省略

行数・列数が多いDataFrameを表示させると、途中を省略して表示する。デフォルトで行数は60行を超えると省略され、列数は画面幅に応じて調整される。以下のコードは、pandasのオプションでdisplay.max_rowsdisplay.max_columnsも表示させている。

この場合、行数に61行をしているので行表示は省略され、列数はコンソールの幅に応じて省略されている(コンソールの幅を変えて実行すると、その幅に応じて納めようと省略される)。

表示行数の設定

表示させる最大行数を変更するには、pandas.set_option()display.max_rows属性を設定する。

表示列数の設定

表示させる最大列数を設定するには、pandas.set_option()display.max_columns属性を設定する。以下の例では20列すべてを表示させていて、コンソールの幅に収まらない列は表単位で改行されている。

ファイルの読み込み

CSVファイル

DataFrameにCSVファイルの読み込みには、pandas.read_csv()を使う。

pandas.read_csv(path)
pathは読み込むCSVのパス

ヘッダー付きCSVファイル

たとえば、以下のようなヘッダー付きのCSVファイル(ex_basic_w_header.csv)を考える。

このファイルが実行ファイルと同じディレクトリにある場合、以下のように__file__を使って読み込むとよい

データには自動的にインデックス番号が付加される。

ヘッダー無しCSVファイル

以下のようなヘッダーがないファイルの場合。

そのまま読み込んでしまうと1行目がヘッダーと解釈されてしまう。

引数にheader=Noneを指定すると1行目からデータとして読み込み、列名には番号が振られる。

引数としてnames=(列名1, 列名2, ...)を指定すると、ヘッダー無しとして読み込まれ、列名がセットされる。

行のスキップ

以下のように、先頭から何行か読み飛ばしたいファイルの時。

引数にskiprowsでスキップする行数を指定する。このとき、最初の行はヘッダーとして解釈される。

ヘッダー行の指定

ヘッダー行を含むファイルでヘッダーの開始行を指定したいときはheaderで開始位置を指定する。指定したヘッダーより前の行は無視される。

インデックス列の指定

以下のファイルは通し番号付きで、番号には列名がない(1行目の1列目が空)。

これをそのままデータフレームに読み込むと、1列目もデータと解釈されてインデックスが自動生成される。

引数にindex_col=0を指定すると、その列がインデックスとして認識される。

index_colを1以上の値にすると、それ以前の列は読み込まれない。ただし指定した列に列名が定義されていると、それもデータとみなされてしまう。

日本語

日本語などマルチバイトの文字を含む場合、対応する文字コードを指定する。

One-hot-encoding

DataFrameのget_dummies()メソッドは、属性データをone-hotの形にエンコードしてくれる。

Tips – 注意点など

配列で生成しない方がいい

コード上で簡単なDataFrameを生成するとき、配列で数値と文字列を混在させるとトラブルになる

DataFrameの行追加の速さ

DataFrameに行を追加する場合、基本的にはリストに変換してリストの状態で行を追加し、それをDataFrameに変換するのが最も速い。いくつかの方法による速さの違いはこちら

行単位/列単位の合計・率の計算

DataFrameオブジェクトの行単位/列単位の合計や、それらを使った率の計算方法

 

ndarray – 配列による要素指定

“Pythonではじめる機械学習”中、27番のコードで気になったので調べた結果。

Scitkit-learnを使ってk-最近傍法の予測結果を保存し、その結果を使って予測されたアヤメの種類を表示させている。

ここでpredictioniris_dataset['target_names']のいずれの型もnumpy.ndarrayであり、ndarrayの引数に整数ではなくてndarrayを使っている。

通常のリストでこれをやると、”リストのインデックスにリストを使ってはダメ”とエラーになる。

ところがndarrayの場合はその引数にndarrayを渡すことができて、結果はndarrayとして帰ってくる。

さらに、引数に渡す配列が複数の要素を持つ場合、各要素を引数とした場合に対応する元の配列の要素が配列として返される。

なお、元の配列がndarrayであれば、引数に普通のリストを渡しても同じ結果が得られる。

 

Python3 – os/os.path

主な関数

os.getcwd()
カレントディレクトリー。プログラム実行直後は実行中のディレクトリーを指している。実行ファイルのディレクトリー情報を得るには__file__を使うとよい
os.path.dirname(dir)
dirのディレクトリーのフルパス。
os.listdir(dir)
dirにあるファイル・ディレクトリーのリスト。
os.chdir(dir)
dirに移動。存在しない場合は’NotADirectoryError’をスローする。

実行例

実行結果

 

ファイル/ディレクトリーの判定

ファイルの判定はos.path.isfile(target)。ディレクトリーの判定はos.path.isdir(target)

実行結果

 

Python3 – sys

プログラムの停止

プログラムを停止するのはsys.exit()

 

sys.argv~コマンドライン引数

sys.argvはコマンドライン引数を配列で返す。0番目の値は実行中のパス付のスクリプト名自体。

 

Python3 – 正規表現 – group()

たとえば次のようなファイル名のテキストがあるとする。

  1. file_name-10.txt
  2. file_name-1.txt

ファイル名本体の末尾にある番号を2桁に統一したいようなとき、1つ目にはマッチせず、2つ目にはマッチさせたい。

この場合、以下のような正規表現でマッチングできる。

ただしこれだけでは、該当するファイル名はわかるが、0の挿入といった部分的な操作ができない。

そのような場合は、正規表現を()で区切り、group()メソッドで部分列を取り出すことができる。

パターン設定で()で区切った部分ごとにグルーピングされ、その各部分を後から再利用できる。なお、group(0)はマッチした部分全体になる。

 

Python3 – enumerateでリストのインデックスが得られる

通常、リストの要素を順番に操作するときにはforループを使う。

enumerate()関数を使うと、リストの要素とそのインデックスを同時に得ることができる。

このインデックスにformat()を使うと書式を設定でき、ファイル名のrenameなどに便利。

 

Python3 – 正規表現の操作

主なreモジュール関数

まず、reモジュール関数の操作をまとめる。以下の文字列をターゲットにする。

re.match()はパターンが先頭でマッチするかどうか。

re.search()はパターンが含まれるかどうか。最初に現れたパターンにのみマッチする。

re.findall()は一致するパターン全てのリストを返す。

re.finditer()は一致するパターンのイテレータを返す。

re.sub()は一致するパターンを置き換え。

re.subn()は一致するパターンを置き換え、その結果と置換回数のタプルを返す。

コンパイル

パターン文字列をコンパイルしパターンオブジェクト化することで、再利用・高速化が可能。この場合、reモジュール関数と同じ名前のメソッドが使える。

マッチオブジェクトの利用

上記のうちmatch()、search()、findall()はマッチオブジェクトを返す。マッチオブジェクトの主なメソッドには、マッチした開始点を返すstart()、終了点(+1)を返すend()、それらをタプルで範囲として返すspan()、マッチした文字列を返すgroup()がある。

複数のマッチした文字列を処理するには、finditer()で順次マッチオブジェクトを取り出すとよい。