Pythonを用いたデータ処理・統計(データサイエンス) ~チュートリアル~

目次


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値

以下の図が、表示される。

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください