アメダス気象データ分析チャレンジ!(Python版)にご参加いただきありがとうございます.本日は,まず,Jupyter Notebookを使って,pythonの基礎知識を学習します.その後,気象データとその他のオープンデータを掛け合わせたデータ分析について理解します.時間の都合上,全てを十分に説明できる時間はありませんが,次の内容の理解のために一つ一つのプログラムを丁寧に読み進めてください.全てのpythonのプログラミングの「いろは」をすべて解説しているわけではありませんので,よく分からないことがあれば自身でGoogleなどで調べてみてください.
早速,Pythonの基礎について学びましょう.
Jupyter Notebook(ジュピター・ノートブック)は,Pythonの手軽なインタラクティブ環境として利用できます.この講義では,このJupyter Notebookの環境を使いながら学習を進めて行きます.まずは,Jupyter NotebookでPythonのコードを記述し実行することから学びましょう.一部,Pythonの基本的なプログラミングについても学習しますが,十分な時間はありませんので各自お気に入りの書籍を見つけて勉強してください.
まずは,Jupyter Notebookを起動してみましょう.macOSの場合はターミナル,Windowsの場合はAnacoda Promptの中で,
$ jupyter notebook
と実行することでJupyter Notebookが起動します.また,左下のWindowsのスタートボタンから,「すべてのプログラム」→「Anaconda3 (64bit)」→「Jupyter Notebook (Anaconda3)」でも起動することができます.
Jupyter Notebookのホーム画面には,幾つかのフォルダやファイルが表示されていると思いますが,Windowsの場合,ローカルディスクの中の「C¥:Users¥(ユーザー名)」の位置となります.今回,皆さんに配布するテキスト一式も,そのフォルダの配下に保存して下さい.拡張子が「.ipynb」となっているファイルが,Jupyter Notebookの出力形式となっています.
新規でNotebookを開く場合には,下の図のように,
ホーム画面上の右上の「New」をクリックして,「Python3」をクリックします.すると次のように,
Jupyter Notebookによるpythonプログラミングの環境ができあがります.ここの上にpythonコードを書いていきます.ブラウザ上でプログラミングができることに驚きますね.
Jupyter Notebookを使えばPythonプログラミングの実行は簡単です.
・(Step 1) セルを追加して(上の「+ボタン」を押す)
・(Step 2) コードを入力して
・(Step 3) 実行する(上の「Runボタン」を押す)
の手順ですぐに実行できます.まずは,画面に「Hello, World!」と出力させてみましょう.Pythonでは,print
文を使います.
print("Hello, World!")
と打ちます.上記の文頭にIn [ ] :
と書かれたセルをクリックすると,pythonコードを入力することができます.pythonでは,画面に文字を表示する場合には,print
という関数を用います.上にある「Run」ボタンを押してみて下さい.結果がその下に表示されると思います.簡単ですね.
新たなコードを追加するときには,左上の「+」ボタンをクリックすると新しいセルができあがります.
もちろん,pythonでは文字を表示するだけでなく計算もできます.
# 足し算
print(1+2)
# かけ算
print(3*4)
# 割り算
print(5/6)
# べき乗
print(7**8)
コードの中の#から始まる行はコメントアウトで無視されます(コメント文といいます).後日見た時に思い出せるようにコメント文をつけておくと良いです.
作成されたNotebookは,画面左上の「File」から「Save as」をクリックして,ファイル名を入力することで保存できます.また,「Download as」をクリックすることで,様々な形式(html等)でも保存できます.
Jupyter Notebookでpythonを実行する最低限の作法は以上となります.Jupyter notebookに記載されたコードは上から順番に実行する必要があります.上に記載されたコードが前提となって処理が進められていきます.皆さんも手を動かしながら,適宜,コードを変更しながら処理を進めてみてください.
Jupyter環境でコードを実行する方法がわかったところで、Pythonの基本をさらに続けます.
まず変数から学びます。以下は,message
という名前の変数に,「python」という文字列を格納し,print
関数でその変数に格納されている値を表示させるというコードです.文字列を作成するときは,シングルクォーテーションまたはダブルクォーテーションで囲みます.
# pythonという文字をmessageという変数に割り当てて画面に表示します.
message = 'python'
print(message)
CやFORTRANなどのプログラミング言語では,変数を扱うときに整数なのか文字なのかを「型」として設定し,これから利用するという宣言をする必要があります.しかし、pythonには変数の型宣言が基本的に必要ないので,変数を使いたいときに値を代入するだけで使えます.
文字列の後ろに「[番号]」を指定すると、文字列の一部を取り出すことができます。これをインデックスと言います.インデックスは「0」から始まります.3つ目の文字を取り出したいならばインデックスは「2」となりますので注意しましょう.
# 1文字ずつ画面に表示します.インデックスは0から始まります.
print(message[0])
print(message[1])
print(message[2])
print(message[3])
print(message[4])
print(message[5])
さて、先ほどは変数に文字を割り当てましたが,もちろん数字を割り当てることもでき,その変数を使って変数同士の演算(足し算など)も可能です.
# 変数dataに1を割り当てて,2,3,4,5…,9,10と順番に足していきます.
data = 1
print(data)
data = data + 2
print(data)
data = data + 3
print(data)
data = data + 4
print(data)
data = data + 5
print(data)
data = data + 6
print(data)
data = data + 7
print(data)
data = data + 8
print(data)
data = data + 9
print(data)
data = data + 10
print(data)
1から順番に10まで足し算をした結果が出力されました.ここでは変数の名前をdata
としましたが,どんな名前でも構いません.何か変数を作成するときは,可能な限り分かりやすい名前で作成しましょう.
次は,リストについて説明します.リストとは複数の値をひとまとめにして扱うための仕組みです.他のプログラム言語で言うところの配列のようなものです.データ分析では配列のような複数の値を一緒に扱うことが多いため,リストは頻繁に使われます.
以下は,1から10まで数字が並んでいるデータを作っています.
# 1から10まで数字が並んだリストdatalistを作り画面に表示します.
datalist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(datalist)
Pythonでリストを表現するには,全体を $[$ と $]$で囲んでカンマで区切ります.先頭からn番目の要素は,「変数名[n]
」のように表記することで取得できます.たとえば,datalist
という要素の先頭はdatalist[0]
,2番目はdatalist[1]
です.文字列の取り出しのときと同様に,インデックス番号は0から始まります.
# リストdatalistの中の2番めの数を取り出して表示します.
print('2番目の数:', datalist[1])
また,リストの要素数はlen
関数を使って,len(datalist)
のように表記すると取得できます.
# len関数でリストの要素の数を出力します.
print('要素数:', len(datalist))
また,リスト型と似たものに,辞書型があります.辞書型を使うと,キーと値をペアにして複数の要素を管理することができます.Pythonで辞書を表現するには,全体を $\{$ と $\}$ で囲んで,{キー:値}のようにコロン区切りで表記します.キーは整数だけではなく,文字列でも指定できます.またリストとは違って,順番は特に関係ありません.
次の例のように,「札幌が気温20℃,相対湿度40%」「仙台が気温25℃,相対湿度45%」「東京が気温35℃,相対湿度50%」などのように,指定した何らかのキーに対して値を設定させたいときに使います.値を設定するときは,辞書データ[キー名]
というように表記します.以下では,辞書型のデータを用意した後に,東京
というキーを参照して,それに対応する50が表示されているところです.
# 辞書型では,辞書データとキー名を紐付けます.
dic_data = {'札幌': [20, 40],
'仙台': [25, 45],
'東京': [35, 50],
'名古屋': [40, 30],
'大阪': [35, 45],
'福岡': [30, 45],
'沖縄': [25, 60]}
# 東京の辞書データを取り出す場合
print(dic_data['東京'])
# 東京の辞書データの中のインデックス番号1(相対湿度)を取り出す場合
print(dic_data['東京'][1])
以上がリストと辞書の簡単な解説になります。
次に,条件分岐を説明します.条件分岐とは,何かの条件で処理を分岐することで,if文を使います.ifの横に指定した条件式(真偽の判定式)を満たしている場合(True
)は,該当の文(はじめにある:
からelse:
の手前まで)が実行され,そうでない場合(False
)は,else:
以下が実行されます.つまり条件を満たすかどうかによって,処理を2分岐できるのです.
以下の処理は,数字の「5」がdatalist
というリストの中に入っているかどうかを判定する例です.5 in datalist
が判定式です.datalist
の中に5が入っていれば,すぐ下に書いてある処理が実行されます.一方,このリストに5が入っていなければ,else
に飛びます.
Pythonのコーディングにおける注意点ですが,if
文などを使うとき,次の行はインデント(字下げ)します.通常は半角スペース4つ分を置きます.Jupyter Notebookではif文を改行すると自動的に半角4文字分のスペースが入ります.
# if文の開始
if 5 in datalist:
# 条件式の結果が真の場合
print('True')
else:
# 条件式の結果が偽の場合
print('False')
# ここでif文は終わり
print('End of Program')
if文の1行目「:」がif文の開始で、字下げがあるところまでが処理の対象です。elseの横にも「:」がありますが,これがelseの中身の処理が開始されることを意味し,これも字下げがあるところまでが処理の対象となります.他のプログラミング言語では,endなどがありますが,Pythonではそれを記載する必要がありません.字下げがなくなった個所から,if文の処理とは別の処理がはじまりますので注意してください.上の例では,最終行のprint('End of Program')
はif文の処理の範囲外となります.
条件分岐のための比較演算子や真偽判定は,次のようにいろいろとあります.真の場合True,偽の場合Falseと表示されます.
#右と左の数字が同じかどうか?
datalist[0] == 1
#右と左の数字が違うかどうか?
datalist[0] != 1
#右の数字が左の数字より小さいかどうか?
datalist[0] < 10
#右の数字が左の数字より大きいかどうか?
datalist[0] > 10
#どちらも成り立っているかどうか?(AND)
(datalist[0] < 5) & (datalist[9] < 5)
#どれか1つでも成り立っているかどうか?(OR)
(datalist[0] < 5) | (datalist[9] < 5)
次に,繰り返し処理の構文を説明します.これはfor
文を使います.for
文は,リストデータなどからデータを1つずつ取り出し,データがなくなるまで繰り返し処理を実行します.
先のdatalist
のリストに対して,先頭から順番に(1から)データを取り出し,データがなくなる(10まで)まで繰り返し処理(取り出した数字の表示と足し算)を実行しています.つまり,1から10までを足し算した結果となります.
#初期値の設定
total = 0
# for 文の開始
for num in datalist:
# 取り出した数を足す
total = total + num
# ここでfor文の終わり
# 最後に合計を表示
print(total)
処理の初めは1をnum
に入れており、0+1=1
となります。次に2をnum
に入れて1+2=3
となり、次に3を取り出して3+3=6
となり・・・,この処理を10になるまで繰り返します.ここでfor
文が終わり,最終的な合計値を表示しています.なお,このfor
文もif
文と同じように,「:」の以下からfor
文がはじまり,字下げがされているところまでがfor
文の処理対象となりますので注意してください.
繰り返し処理をするには,for
文以外にwhile
文があります.while
文は,条件が成り立っている間は、ずっと繰り返し処理する構文です.
次の例は,変数num
の値を表示して,1ずつ加えていき,その値が10より大きくなった時点で,処理を終えるというものです.なお,こちらもif
文やfor
文と同じように:の行でwhile
文がはじまり,字下げがあるところまでが処理の対象となります.
# 初期値の設定
num = 1
total = 0
# while文の開始
while num <= 10:
#numをtotalに足す
total = total + num
#numを1足す
num = num + 1
# ここでwhile文の終わり
# 最後に合計を表示
print(total)
関数は,一連の処理をひとまとめにする仕組みです.関数を作成すると,同じような処理を何度か実行したいときに便利です.また,処理をまとめておくと,後でコードを修正するときにも便利です.
下記に示すsea_level_pressure
関数の例は,3つの数字(気圧p1
と気温t1
と標高z1
)をインプット(これを引数といいます)として,海面更正気圧p0
の結果を返す関数です.気圧は様々な高度で計測されていますが,上空に行けば行くほど気圧が下がるため,地上天気図を作成するためには海面補正をする必要があります.これが海面更正気圧です.海面更正気圧は,
$p_0 = p_1 \displaystyle{\left( \frac{T_0 - \Gamma z_1 }{ T_0 } \right)^{-g/R_d \Gamma}}$
によって計算できます.ここで,海面更正気圧$p_0$は標高0mにおける気圧p0
です.気圧$p_1$,気温$t_1$,標高$z_1$は観測点1の気圧p_1
,気温t_1
,高度z_1
です.$\Gamma$は気温減率$=$0.65$K$/100$m$です.$g$は重力加速度$=$9.81 $m/s^2$です.$R_d$は乾燥空気の気体定数$=$287.0 $J K^{-1} kg^{-1}$です.
書き方としては,defの後に関数名,引数があれば,()の中に,引数名を記述します.この引数が入力となって,return
で結果を返し(返り値といいます),これが出力になります.なお,このdefine
もif
やfor
やwhile
と同じように,「:」の以下からdef
がはじまり,字下げがされているところまでがdef
文の処理対象となります.
# 気圧の高度補正をする関数
def sea_level_pressure(p1, t1, z1):
# 重力加速度
g=9.81
# 乾燥空気の気体定数
rd=287.0
# 気温減率
gamma=0.65/100
# ℃ -> K
t1=t1+273.15
# z=0での気温
t0=t1+gamma*z1
# 気圧の高度補正式
p0=p1*(((t0-gamma*z1)/t0)**(-g/(rd*gamma)))
return p0
関数を実行することを,関数を呼び出すと言います.作成した関数を呼び出すときには,関数名を書いて,引数が必要なときには,引数を与えて,実行します.関数は引数なしでも設定できます.以下は,引数として,気圧p1
は940hPa,気温t1
は15℃,標高z1
は500.0mを与えて,上の関数により海面更正気圧を計算しています.
# 観測点の地表面気圧 hPa
p1=940.0
# 観測点の気温 ℃
t1=15.0
# 観測点の標高 m
z1=500.0
print("海面更正気圧[hPa]:", sea_level_pressure(p1,t1,z1))
Numpy(ナンパイ)は,科学計算でもっともよく使われる基本的なライブラリです.多次元配列を処理することができるなど,機能的に優れているだけでなく,C言語で書かれたモジュールであるため処理が高速なのも特徴です.
ここでは、Numpyを次のようにしてインポートします.
1行目では,「as np
」としているので,以降のプログラムでは,Numpyライブラリを「np.機能名
」と表記することで使えます.機能はメソッドとも言います.
そして2行目はマジックコマンド(Jupyter Notebookの中だけで有効)です.結果を小数点何桁まで表示するのかという指定をします.ここでは,小数第3位まで表示するようにしました.
# Numpyライブラリの読み込み
import numpy as np
# 小数第3位まで表示という意味
%precision 3
まずは、1から10までの配列を作成してみましょう.Numpyにおいて,配列はarray
オブジェクトとして構成されます.これは,np.array
のように,「インポートしたときにas
の部分に付けた名前」と「array
」をピリオドでつなげた名称で指定します.
10個の要素を持つ配列を作成する例を以下に示します.
# リストの作成
datalist=[5, 8, 4, 3, 7, 1, 6, 10, 2, 9]
# Numpy配列の作成
data = np.array(datalist)
print(data)
Pythonにおいて,Numpyではないふつうの配列(リスト)に対して,すべての要素を係数倍にするには,for
を使ったループ処理が必要となります.以下は要素を2倍にする例です.空のdatalist1
を作って,datalist
から取り出した要素を1つ1つ2倍して,datalist1
の末尾に追加(append
メソッド)しています.
# for文で要素を2倍する場合
datalist1=[]
for element in datalist:
datalist1.append(element*2)
print(datalist1)
しかし,Numpyの場合は,たとえば2倍にするのであれば,次のように,配列に対して「*2
」と記述するだけですべての要素が2倍になるので簡単です.
# numpyで要素を2倍する場合
print(data * 2)
それぞれの要素での掛け算や割り算も,for
文などを使わずに簡単に計算できます.
# それぞれの要素同士での演算
print('掛け算:', data * data)
print('累乗:', data ** 2)
print('割り算:', data / data)
データを並べ替えるには,sort
メソッドを使います.デフォルトでは,昇順(小さい数字から大きい数字)になります.
# 現在の値を表示
print('そのまま:', data)
# ソートした結果を表示
data.sort()
print('ソート後:', data)
なお,sort
メソッドは,元のデータ(data
)を置き換えるので注意しましょう.降順(大きい数字から小さい数字)にしたい場合は,data[::-1].sort()
のように,スライスを使って操作します.スライスはPythonの機能で,[n:m:s]
のように記述すると,要素の中の「n
番目からm-1
番目を,s
ずつ飛ばして取り出す」という意味になります.インデックス番号のn
やm
は,0から始まることに注意してください.n
やm
を省略したときは「すべて」という意味になります.またs
が負のときは先頭からではなく,末尾から取り出すことを意味します.つまり,[::-1]
は,「末尾から1つずつ取り出す」という意味になります.
print("末尾から要素を1つずつ取り出す",data[::-1])
print("5番目から9番目までの要素を順に取り出す",data[5:10:1])
print("最初から最後まで1つ飛びで取り出す",data[::2])
Numpyのarrayデータは,min
メソッドやmax
メソッドを呼び出すことで,最小値や最大値なども求めることができます.cumsum
というメソッドは積上(前から順に足し上げていく)演算です.
# 最小値を計算します.
print('Min:', data.min())
# 最大値を計算します.
print('Max:', data.max())
# 合計を計算します.
print('Sum:', data.sum())
# 積み上げを計算します.
print('Cum:', data.cumsum())
Numpyを使うと行列計算もできます.
まずは,行列の作成方法から説明します.次の例は,0〜8までの数字を3×3行列で表現するものです.arange
関数は指定した連続した整数を発生する機能を持ちます.arrange(9)
とした場合、0から8までの整数を発生します.それをreshape
関数で3×3の行列に分割しています.
これで変数array1
に3×3の行列が作られます.再びデータを1次元に戻す場合には,ravel
メソッドを使います.
# 1行×9列の行列(0~8まで)を生成します.
print(np.arange(9))
# 3行×3列の行列(0~8まで)を生成します.
array1 = np.arange(9).reshape(3,3)
print(array1)
# 再び1行9列のデータに戻します.
print(array1.ravel())
行列から,行や列のみを抜き出したいときは,「[行範囲:列範囲]」のように表記します.それぞれの範囲は,「開始インデックス,終了インデックス」のように,カンマで区切って指定します.開始インデックスや終了インデックスを省略したときは,それぞれ「最初から」「末尾まで」という意味になります.たとえば,次のように「[0,:]
」を指定すると,「行は1行目」「列はすべて」という意味になるので,1行目のすべての列を取り出すことができます.
# 1行目を取り出します.
print(array1[0,:])
# 1列目を取り出します.
print(array1[:,0])
行列の掛け算をしてみましょう.この計算方法がわからない方は,線形代数の復習をしてください.まずは,掛け算する対象とする行列を作成しましょう.次の例では、3×3の行列を作成し,変数array2
に代入しています.この行列と,先のarray1
の行列を掛け算してみましょう.
行列の掛け算では,dot
関数を使います.間違えて*
を使うと,行列の掛け算ではなく、それぞれの要素を掛け算してしまうので注意しましょう.
array2 = np.arange(9,18).reshape(3,3)
print(array2)
# 行列の掛け算
array3 = np.dot(array1, array2)
print(array3)
# 行列の要素同士の掛け算
array4 = array1*array2
print(array4)
Pandas(パンダス)は,Pythonで機械学習を行う前のデータの前処理をするときに便利なライブラリです.さまざまなデータのさまざまな加工処理をスムーズに柔軟に実施することができ,表計算やデータの抽出,検索などの操作ができるようになります.具体例を挙げると,顧客データの中からある条件(女性だけ)を満たす行を抽出したり,ある軸(男女別など)を設定してそれぞれの平均値(身長,体重など)を算出したり,データを結合するなどの操作ができます.
まず,Pandasのライブラリをインポートします.「import pandas as pd
」としてPandasをインポートしているので,「pd.機能名
」と表記することでPandasライブラリを使えるようになっています.以下ではさらに,二次元の配列を扱うときのDataFrame
ライブラリをインポートします.
import pandas as pd
DataFrame
オブジェクトは2次元の配列(辞書型)です.下記は,番号
、住所
、年齢
、名前
の4つの列を持つデータ構造を示した例です.Jupyter notebookでは,データフレーム形式は表形式できれいに表示されます.
#辞書の用意
dictdata1 = {'地点番号':['18273','62078','61111','46106','44132','14163','52146'],
'地点名':['根室','大阪','舞鶴','横浜','東京','札幌','高山'],
'気温':[1.0,9.1,4.8,8.5,6.6,1.2,2.3],
'相対湿度':[79,81,98,65,76,65,90],
'都道府県':['北海道','大阪','京都','神奈川','東京','北海道','岐阜']}
print(dictdata1)
#PandasのDataframeに割り当てる
dfdata1 = pd.DataFrame(dictdata1)
dfdata1
一番左列に表示されている0, 1, 2, 3, 4, 5, 6
の値は,インデックスの値です.データフレームはインデックスを変更したり,インデックスとして文字を指定したりすることもできます.
次のようにインデックスを指定すると,dictdata1
の値に対して新しいインデックスを指定したdfdata1
というデータフレームを作ることができます.
dfdata1 = pd.DataFrame(dictdata1,index=['a','b','c','d','e','f','g'])
dfdata1
データフレームDataFrameは,さまざまな行列操作ができます.行列の転置のように,行と列を入れ替える場合には,.T
メソッドを使います.
# 転置
dfdata1.T
特定の列だけを指定したいときは、データの後にその列名を指定します。複数の列を指定したいときは、それらをPythonのリストの形式で指定します。
# 列名の指定(1つの場合)
dfdata1[['気温']]
# 列名の指定(1つの場合)これでもよい
dfdata1.気温
# 列名の指定(複数の場合)
dfdata1[['地点番号', '気温']]
データフレームでは,特定の条件を満たすデータだけを取り出したり,複数のデータを結合したりすることもできます.次の例は,データのうち,住所
が東京
のみのデータを抽出する例です.この処理は,dfdata1['住所'] == '東京'
がTrue
であるデータをすべてdfdata1
から抽出するもので,フィルターの役割を果たしています.
# 条件(フィルター)
dfdata1[dfdata1['都道府県'] == '北海道']
複数の条件をつけることもできます.以下は,住所が東京か大阪であるデータを抽出しています.
# 複数条件(フィルター)
dfdata1[(dfdata1['都道府県'] == '東京') | (dfdata1['都道府県'] == '大阪')]
以下は,相対湿度
が60~80%であるデータを抽出しています.
# 複数条件(フィルター)
dfdata1[(dfdata1['相対湿度'] >= 60 ) & (dfdata1['相対湿度'] <= 80)]
データフレームは,必要のない列や行を削除したり,他のデータフレームと結合したりすることもできます。ある特定の列や行を削除するにはdrop
メソッドを実行します。axis
パラメータに軸を指定します。「axis=0
が行」「axis=1
が列」です.なお,このaxis
パラメータは他の場面でも使うので覚えておいてください.
・行削除の場合:1つ目の引数に削除したい行のインデックスをリストとして指定します.axis
パラメータには「0
」を指定します.
・列の削除の場合:1つ目の引数に削除したい列名をリストとして指定します.axis
パラメータには「1
」を指定します.
次の例は、年齢
列を削除する例です.
dfdata1.drop(['相対湿度'], axis = 1)
データフレーム同士は結合することもできます.データ分析ではさまざまなデータがある場合に,それらを結合して分析することは多々あります.まずは例として,結合先のデータフレームを,次のようにdfdata2
という変数で用意します。
# 別のデータの準備
dictdata2 = {'地点番号':['62078', '61111','46106','14163','52146'],
'緯度':[34.68, 35.45, 35.44, 43.06, 36.16],
'降水':['なし','あり','なし','あり','あり']}
dfdata2=pd.DataFrame(dictdata2)
dfdata2
そして,はじめに作ったdfdata1
とこのdfdata2
を結合して,新たにdfdata3
を作ります.
結合するにはmerge
メソッドを使います.キーを明示しないときは,自動で同じキーの値であるものを見つけて結合します.この例の場合,キーは地点番号
です.'62078'
, '61111'
,'46106'
,'14163'
,'52146'
が共通であるため,それが合致するデータが結合されます.
# データのマージ
dfdata3=pd.merge(dfdata1,dfdata2)
dfdata3
データフレームのデータは,ソートすることもできます.値だけではなく,インデックスをベースにソートできます.まずは先ほど作ったサンプルデータdfdata2
を次のように定義します.ソートの効果がわかりやすくなるよう,わざとデータを適当な順で並べてあります.
dfdata2 = pd.DataFrame(dictdata2,index=['e','d','b','a','c'])
dfdata2
インデックスでソートするには,次のようにsort_index
メソッドを実行します.
# indexによるソート
dfdata2.sort_index()
値でソートする場合には,次のようにsort_values
メソッドを使います.
# 値によるソート、デフォルトは昇順
dfdata2.地点番号.sort_values()
DataFrame
オブジェクトでは,データを集計することできます.さらにgroupby
メソッドを使うと,ある特定の列を軸とした集計ができます.以下は「降水
の列」を軸として,気温
の平均を算出する例です.スコア平均を計算するにはmean
メソッドを使います.他にも,最大値を計算するmax
メソッドや最小値を計算するmin
メソッドなどもあります.
# データのグループ集計
dfdata3.groupby('降水')['気温'].mean()
DataFrame
オブジェクトでは、相関係数のような統計値も計算できます.以下は「緯度
の列」と「気温
の列」を軸として、緯度と気温の相関係数を算出している例です.相関係数は0に近ければ無相関,1に近ければ正の相関,-1に近ければ負の相関となります.
# 緯度と気温の相関係数
print(dfdata3['緯度'].corr(dfdata3['気温']))
特に気象データを分析する際には,日付の処理をすることがあります.datetime(デイトタイム)をインポートすると,日時(日付や時刻)の処理が可能となります.datetimeライブラリでは,datetime.datetime
,datetime.timedelta
オブジェクトがよく使われます.以下のように,インポートします.
from datetime import datetime, timedelta
まず,現在の日時を得るには,datetime.now()
メソッド使います.
dt_now = datetime.now()
print(dt_now)
もちろん,任意の日付,時刻を設定することもできます.
dt = datetime(2021, 5, 13, 13, 0, 0, 0)
print(dt)
dt
から日付(何年何月何日)だけを取り出すにはdate()
メソッドを使います.年のみを取り出す場合はyear
メソッド,月のみを取り出す場合はmonth
メソッド,日にちのみを取り出す場合はday
メソッドとなります.
print(dt.date())
print(dt.year)
print(dt.month)
print(dt.day)
日付から曜日を取り出した場合には,weekday()
メソッドを使います.月曜日が0,火曜日が1,・・・土曜日が5,日曜日が6と出力されます.
weekdaylist = ['月曜日', '火曜日', '水曜日', '木曜日', '金曜日', '土曜日', '日曜日']
print(dt.weekday())
print(weekdaylist[dt.weekday()])
dt
から時刻(何時何分何秒)だけを取り出すにはtime()
メソッドを使います.時間のみを取り出す場合はhour
メソッド,分のみを取り出す場合はhour
メソッド,秒のみを取り出す場合はhour
メソッドとなります.
print(dt.time())
print(dt.hour)
print(dt.minute)
print(dt.second)
datetime
オブジェクト同士の引き算からtimedelta
オブジェクトを作ることができます.2つの日時の時間差,経過時間を表したりできます.以下は,dt
とdt_now
の時間差,経過時間を表します.
td = dt - dt_now
# 時間差,経過時間
print(td)
# 日数で表す
print(td.days)
# 秒数で表す
print(td.seconds)
timedelta
オブジェクトを使うと,1週間後の日付や4時間後の時刻などを簡単に計算して取得できます.1週間後の日時を表したい場合には,次のようにweeks=1
かdays=7
とする.
td_1w = timedelta(days=7)
print(dt + td_1w)
td_4h = timedelta(hours=4)
dt_4h = dt + td_4h
print(dt_4h)
strftime()
メソッドを使うと,datetimeオブジェクトから日時の情報を任意の書式の文字列として変換できます.
%d
: 0埋めした10進数で表記した月中の日にち
%m
: 0埋めした10進数で表記した月
%y
: 0埋めした10進数で表記した西暦の下2桁
%Y
: 0埋めした10進数で表記した西暦4桁
%H
: 0埋めした10進数で表記した時 (24時間表記)
%I
: 0埋めした10進数で表記した時 (12時間表記)
%M
: 0埋めした10進数で表記した分
%S
: 0埋めした10進数で表記した秒
%f
: 0埋めした10進数で表記したマイクロ秒(6桁)
%A
: ロケールの曜日名
%a
: ロケールの曜日名(短縮形)
%B
: ロケールの月名
%b
: ロケールの月名(短縮形)
%j
: 0埋めした10進数で表記した年中の日にち(正月が'001')
%U
: 0埋めした10進数で表記した年中の週番号 (週の始まりは日曜日)
%W
: 0埋めした10進数で表記した年中の週番号 (週の始まりは月曜日)
例えば,以下のように様々な日付や日時の表現ができます.
print(dt.strftime('%Y-%m-%d %H:%M:%S'))
print(dt.strftime('%y%m%d'))
print(dt.strftime('%A, %B %d, %Y'))
文字列ではなく数値として月や日にちを得たい場合には,int()
で整数型にすればよいです.
month_num = int(dt.strftime('%m'))
print(month_num)
データ分析をする上で,対象となるデータを可視化することはとても重要です.単に数字を眺めているだけでは,データに潜む傾向がなかなか見えなかったりしますが,データをビジュアル化することで,データ間の関係性なども見えてきます.ここでは,主にMatplotlib
とSeaborn
を使って,データを可視化する基本的な方法を身につけましょう.
Matplotlib(マットプロットリブ)では、描画に関するほとんどの機能が「pyplot.機能名
」で提供されています.この機能を使うためには,「import matplotlib.pyplot as plt
」とインポートし,「matplotlib.pyplot.機能名
」とフルネームで書くのではなく「plt.機能名
」と略記できるようにしています.SeabornはMatplotlibのグラフを,さらにきれいにするライブラリです.インポートするだけでグラフがきれいになり,また,いくつかの追加のスタイルを指定できるようになります.以下の「%matplotlib inline
」は,Jupyter Notebook上にグラフを表示するためのマジックコマンドです.
# Matplotlib と Seabornの読み込み
# pyplotにはpltの別名で実行できるようにする
import matplotlib.pyplot as plt
import seaborn as sns
# Jupyter Notebook上でグラフを表示させるために必要なマジックコマンド
%matplotlib inline
Matplotlabでは、さまざまなグラフを描けますが,まずは,データ分析でよく使う散布図から始めましょう.散布図は,2つの組み合わせデータに対して,x−y座標上に点をプロットしたグラフです.plt.plot(x, y, 'o')
で描写でき,最後の引数はグラフの形状を指定するもので'o'
は点で描くという意味です.その他の動作については,コード中のコメントを参考にしてください.散布図を描くと,2変数の関係性などが見えてきます.
# x軸のデータ(0から1までの一様分布の乱数生成)
x = np.random.rand(100)
# y軸のデータ(0から1までの一様分布の乱数生成)
y = np.random.rand(100)
# グラフの大きさ指定(10を変更してみてください)
plt.figure(figsize=(10, 10))
# グラフの描写
plt.plot(x, y, 'o')
#以下でも散布図が描ける
#plt.scatter(x, y)
# タイトル
plt.title('Sin')
# Xの座標名
plt.xlabel('X')
# Yの座標名
plt.ylabel('Y')
# grid(グラフの中にある縦線と横線)の表示
plt.grid(True)
連続した値を与えれば,plot
による描画は点ではなく曲線として示すことができます.たとえば次の例は,時系列など連続した点を曲線として描くものです.なお,linspace(0, 2*np.pi,100)
は0から$2 \pi$までの数を100個に分割した数字のリストを作成するものです.
# x軸のデータ(0から2πまでを100刻み(均等割)のデータを作成する)
x = np.linspace(0, 2*np.pi, 100)
# y軸のデータ(sinの計算)
y = np.sin(x)
# グラフの大きさ指定(20や6を変更してみてください)
plt.figure(figsize=(20, 6))
# グラフの描写
plt.plot(x, y, label='Label')
# label=とlegendでラベルをつけることが可能
plt.legend()
# タイトル
plt.title('Sin')
# Xの座標名
plt.xlabel('X')
# Yの座標名
plt.ylabel('Y')
# grid(グラフの中にある縦線と横線)の表示
plt.grid(True)
subplot
を使うと,グラフを複数に分けることができます.以下は,2行1列のグラフを作成し,1番目と2番目と番号を指定して表示する例です.
# グラフの大きさを指定
plt.figure(figsize=(20, 6))
# 2行1列のグラフの1つ目
plt.subplot(2,1,1)
# -10から10まで100個に分割した数字のリストを作成する
x = np.linspace(-10, 10,100)
# 1つ目の時系列
plt.plot(x, np.sin(x))
# Xの座標名
plt.xlabel('X')
# Yの座標名
plt.ylabel('Y')
# grid(グラフの中にある縦線と横線)の表示
plt.grid(True)
# 2行1列のグラフの2つ目
plt.subplot(2,1,2)
# -10から10まで100個に分割した数字のリストを作成する
y = np.linspace(-10, 10,100)
# 2つ目の時系列
plt.plot(y, np.sin(2*y))
# Xの座標名
plt.xlabel('X')
# Yの座標名
plt.ylabel('Y')
# grid(グラフの中にある縦線と横線)の表示
plt.grid(True)
subplot
を使って,1枚の図に2つのグラフを表示することもできます.以下は,1行1列のグラフを作成し,2つのグラフを同じ図の中に表示しています.2つ目のグラフは1つ目のグラフのx軸と同じ物を使うので,twinx()
メソッドを使います.1つ目のグラフはax1というインスタンスで,2つ目のグラフはax1というインスタンスで管理され,2つ目のグラフのy軸は第2軸として図の右側に現れます.逆に,y軸を共有して,x軸を2軸にする時はtwiny()
メソッドを使います.2つのグラフは振幅が10倍の大きさで異なりますが,y軸を2軸で表現することによって2つのデータを比較しやすくなります.
# グラフの大きさを指定
plt.figure(figsize=(20, 6))
# 1行1列のグラフの1つ目
ax1=plt.subplot(1,1,1)
# 2つ目のグラフのx軸を共有する
ax2 = ax1.twinx()
# x軸の設定
x = np.linspace(-10, 10,100)
# 1つ目のグラフ
ax1.plot(x, np.sin(x), color='blue', label='data 1')
# 2つ目のグラフ
ax2.plot(x, 10*np.sin(2*x), color='red', label='data 2')
ax1.set_title('data 1 and data 2')
ax1.set_xlabel("X")
ax1.set_ylabel("Y1")
ax2.set_ylabel("Y2")
ax1.legend(loc='upper left')
ax2.legend(loc='upper right')
● Pythonの基礎として,変数,リスト,辞書,条件分岐,繰り返し,関数の基本を学びました.
● 数値計算の基本的な演算のためのNumpyの基本を学びました.
● データの前処理のためのPandasの基礎を学びました.
● 日付処理のためのdatetimeの基礎を学びました.
● 作図のためのMatplotlibの基礎を学びました.
次の「アメダス気象データ分析チャレンジ!(Python版) 1日目~実践編~」のための基本的なpythonの文法について理解できと思います.必要があれば,ここに戻ってきて復習してください.また,困ったことがあれば,google検索などでインターネット上の情報を調べてみましょう.大抵のことは検索で事足ります.