目次
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値
以下の図が、表示される。







