目次
1. 目的
2. チュートリアル
3. 準備
4. データ取得
5. CSVファイルを読み込み
5.1. Pandasを使ったデータフレーム(DataFrame)のアクセス
5.2. 演算
6. 図示
6.1. Matplotlibを用いたシンプルな方法
6.2. seabornを用いた図示
7. 簡単なデータクリーニングと探索的分析
1. 目的
- Pythonを用いた簡単なデータ処理・統計(データサイエンス)
2. チュートリアル
3. 準備
必要なライブラリをインストールする。
インストールする際は、シャープ(#)抜きで、Shell Script(bash)で実行する。
# pip3 install jupyter # pip3 install numpy # pip3 install scipy # pip3 install pandas # pip3 install matplotlib # pip3 install seaborn # pip3 install requests
4. データ取得
ウェブスクレイピングを使って、ウェブページから情報を取得する。
import requests # for HTTP requests (web scraping, APIs) import os # ウェブページから情報を取得 r = requests.get("https://github.com/adambard/learnxinyminutes-docs") print(r.status_code) # "200"であればアクセス成功 print(r.text) # 取得したウェブページのテキストを表示
以下のような、レスポンス(200, アクセス成功)と情報が取得できる。
200 <!DOCTYPE html> <html lang="en" data-color-mode="auto" data-light-theme="light" data-dark-theme="dark"> <head> <meta charset="utf-8"> <link rel="dns-prefetch" href="https://github.githubassets.com"> <link rel="dns-prefetch" href="https://avatars.githubusercontent.com"> <link rel="dns-prefetch" href="https://github-cloud.s3.amazonaws.com"> <link rel="dns-prefetch" href="https://user-images.githubusercontent.com/"> ... <省略>
取得した情報をテキストに保存するには、以下のコマンドを実行する。
# テキストを保存: print(os.getcwd()) # 現在作業しているディレクトリ(カレントディレクトリ)を確認 with open("learnxinyminutes.html", "wb") as f: f.write(r.text.encode("UTF-8"))
インターネット経由で、CSVファイルをダウンロードするには、以下のコードを実行。
# インターネット経由で、CSVファイルをダウンロード fp = "https://raw.githubusercontent.com/adambard/learnxinyminutes-docs/master/" fn = "pets.csv" # アクセス r = requests.get(fp + fn) print(r.text)
取得したCSVファイルには、以下のような情報が記載されている。
name,age,weight,species
“fluffy”,3,14,”cat”
“vesuvius”,6,23,”fish”
“rex”,5,34,”dog”
# CSVファイルを保存: with open(fn, "wb") as f: f.write(r.text.encode("UTF-8"))
5. CSVファイルを読み込み
Pandas
ライブラリを用いて、CSVファイルを読み込む。
import pandas as pd import numpy as np import scipy as sp # CSVファイルを読み込み fn = "pets.csv" pets = pd.read_csv(fn) print(pets)
Pandas
ライブラリで読み込んだCSV情報は、以下の通り。
name | age | weight | species | |
---|---|---|---|---|
0 | fluffy | 3 | 14 | cat |
1 | vesuvius | 6 | 23 | fish |
2 | rex | 5 | 34 | dog |
5.1. Pandasを使ったデータフレーム(DataFrame)のアクセス
Pandasを使ったデータフレーム(DataFrame)のアクセス方法は、次の通り。
例えば、「age」列にアクセスする場合、次のようになる。
# 2種類のアクセス方法 print(pets.age) print(pets["age"])
0 3
1 6
2 5
Name: age, dtype: int64
0 3
1 6
2 5
Name: age, dtype: int64
列と行にアクセスするには、次のようにする。
# name列の内2行目を表示 print(pets.name[1]) # 'vesuvius' # species列の内1行目を表示 print(pets.species[0]) # 'cat' # weight列の内3行目を表示 print(pets["weight"][2]) # 34 # age列の内0-1行目を表示 print(pets.age[0:2]) # 0 3 # 1 6
vesuvius
cat
34
0 3
1 6
Name: age, dtype: int64
データフレームの上にある情報を抜き出すには.head
メソッド、、下にある情報を抜き出すには.tail
メソッドを使うとよい。
# 上から2行を表示 print(pets.head(2))
name | age | weight | species | |
---|---|---|---|---|
0 | fluffy | 3 | 14 | cat |
1 | vesuvius | 6 | 23 | fish |
# 下から1行を表示 print(pets.tail(1))
name | age | weight | species | |
---|---|---|---|---|
2 | rex | 5 | 34 | dog |
5.2. 演算
Pandasのデータフレームを用いた演算も可能である。
# age列の合計した後2倍 print(sum(pets.age) * 2) # 28 # weight列の最大値と最小値の差 print(max(pets.weight) - min(pets.weight)) # 20
28
20
6. 図示
ウェブから取得したしたデータを、matplotlib
ライブラリを用いて図示する。
# 必要なライブラリをインポート import matplotlib as mpl import matplotlib.pyplot as plt # %matplotlib inline # Jupyter Notebookを使うときに実行
6.1. Matplotlibを用いたシンプルな方法
ヒストグラムを図示するには、次の通り。
# ヒストグラム plt.hist(pets.age) # 図のプロパティ plt.xlabel("age") # 横軸名 plt.ylabel("weight") # 縦軸名 # 表示 plt.show()
箱ひげ図を図示するには、以下のコードを実行。
# 箱ひげ図 plt.boxplot(pets.weight) # 図のプロパティ plt.xlabel("age") # 横軸名 plt.ylabel("weight") # 縦軸名 # 表示 plt.show()
散布図を図示するには、以下のコードを実行。
# 散布図 plt.scatter(pets.age, pets.weight) # 図のプロパティ plt.xlabel("age") # 横軸名 plt.ylabel("weight") # 縦軸名 # 表示 plt.show()
6.2. seabornを用いた図示
seaborn
ライブラリを用いて、図示する方法もある。seaborn
ライブラリは、matplotlib
ライブラリよりも簡単に複雑な図が作成できる点で優れている。
棒グラフを作るには、以下の通りになる。
import seaborn as sns # seabornを用いた棒グラフ sns.barplot(pets["age"]) # 表示 plt.show()
Rでよく用いられるggplotを使った図示も、Pythonで実行可能である。
# Rでよく用いられるggplotを使った図示 from ggplot import ggplot(aes(x="age",y="weight"), data=pets) + geom_point() + labs(title="pets") # 表示 plt.show()
7. 簡単なデータクリーニングと探索的分析
データを分析する際には、欠損値や表記ゆれといったある意味汚いデータをきれいにするという、データクリーニングが前処理として重要である。
# 神聖ローマ皇帝のデータを取得 url = "https://raw.githubusercontent.com/adambard/learnxinyminutes-docs/master/hre.csv" r = requests.get(url) # CSVファイルに書き込み fp = "hre.csv" with open(fp, "wb") as f: f.write(r.text.encode("UTF-8")) # CSVファイルを読み込み hre = pd.read_csv(fp) # 先頭から5行を表示 print(hre.head())
以下のような情報が、出力される。
Ix | Dynasty | Name | Birth | Death | Coronation 1 | Coronation 2 | Ceased to be Emperor | |
---|---|---|---|---|---|---|---|---|
0 | NaN | Carolingian | Charles I | 2 April 742 | 28 January 814 | 25 December 800 | NaN | 28 January 814 |
1 | NaN | Carolingian | Louis I | 778 | 20 June 840 | 11 September 813 | 5 October 816 | 20 June 840 |
2 | NaN | Carolingian | Lothair I | 795 | 29 September 855 | 5 April 823 | NaN | 29 September 855 |
3 | NaN | Carolingian | Louis II | 825 | 12 August 875 | Easter 850 | 18 May 872 | 12 August 875 |
4 | NaN | Carolingian | Charles II | 13 June 823 | 6 June 823 | 29 December 875 | NaN | 6 October 877 |
ここでは、”Birth”と”Death”列をクリーニングして、新たに”BirthY”と”DeathY”列を生成する。具体的には、日月を表す英単語・数字を除去して数値のみ残す、つまり西暦のみ残す(例:”28 January 814″から”814″のみを残す)。
# "Birth"と"Death"列をクリーニング import re # 正規表現を扱うモジュール rx = re.compile(r'\d+$') # 末尾の数字を検索 from functools import reduce # 末尾にある数字3桁を取得 # 例:"January 814"から"814"を取得 def extractYear(v): return(pd.Series(reduce(lambda x, y: x + y, map(rx.findall, v), [])).astype(int)) # クリーニング実行 hre["BirthY"] = extractYear(hre.Birth) hre["DeathY"] = extractYear(hre.Death) # 先頭から5行を表示 print(hre.head())
“Birth”と”Death”列のデータクリーニング後、次のようなデータになる。
“BirthY”と”DeathY”列をみると、日月を表す英単語・数字が、無くなり西暦のみ残ったことに注目。
Ix | Dynasty | Name | Birth | Death | Coronation 1 | Coronation 2 | Ceased to be Emperor | BirthY | DeathY | |
---|---|---|---|---|---|---|---|---|---|---|
0 | NaN | Carolingian | Charles I | 2 April 742 | 28 January 814 | 25 December 800 | NaN | 28 January 814 | 742 | 814 |
1 | NaN | Carolingian | Louis I | 778 | 20 June 840 | 11 September 813 | 5 October 816 | 20 June 840 | 778 | 840 |
2 | NaN | Carolingian | Lothair I | 795 | 29 September 855 | 5 April 823 | NaN | 29 September 855 | 795 | 855 |
3 | NaN | Carolingian | Louis II | 825 | 12 August 875 | Easter 850 | 18 May 872 | 12 August 875 | 825 | 875 |
4 | NaN | Carolingian | Charles II | 13 June 823 | 6 June 823 | 29 December 875 | NaN | 6 October 877 | 823 | 823 |
次に、”BirthY”と”EstAge”の散布図を作成する。
# "BirthY"と"DeathY"列から年齢を算出し、"EstAge"列に格納 hre["EstAge"] = hre.DeathY.astype(int) - hre.BirthY.astype(int) # "BirthY"と"EstAge"の散布図 sns.lmplot("BirthY", "EstAge", data=hre, hue="Dynasty", fit_reg=False) # 図示 plt.show()
scipy
ライブラリを用いれば、統計処理も可能である。
ここでは、”BirthY”と”EstAge”の回帰分析を実行する。回帰直線の傾き・R^2値・p値が算出可能である。
# scipyライブラリで回帰分析 from scipy import stats (slope, intercept, rval, pval, stderr) = stats.linregress(hre.BirthY, hre.EstAge) # 傾き print(slope) # 0.0042153573174446585 # R^2値 print(rval2) # 0.011132475593918311 # p値 print(pval) # 0.49032107445388495 # seabornを用いて散布図と回帰直線を図示 sns.lmplot("BirthY", "EstAge", data=hre) # 図示 plt.show()
0.0042153573174446585 # 傾き
0.011132475593918311 # R^2値
0.49032107445388495 # p値
以下の図が、表示される。