乙Py先生のプログラミング教室

乙Py先生のプログラミング教室
初学者のためのプログラミング学習サイト

pythonのライブラリの中で
最もデータサイエンティストが使うであろう
ライブラリがコレではないかなと
思うライブラリです。

pandas公式

APIリファレンス


データフレームという型のデータ形式で
データの集計や可視化を行う事のできるライブラリです。
jupyter notebookでの詳しい使い方を説明してゆきましょう


まずはライブラリをインポート、別名をpdとしておきます
ついでにnumpyも加えておきましょう
importには少しだけ時間がかかるようです
import pandas as pd
import numpy as np

また可視化をするためのライブラリも別途インポートしておきます。
import matplotlib
import matplotlib.pyplot as plt
%matplotlib inline
最後の行のinline指定はjupyter上で可視化をさせるためのコードで
これがないと別枠(window)に表示されてしまいます。


データフレームについて

データフレームはカラムとインデックスを持ち
エクセルの表の様な構造をしています。

DataFrame(引数)

引数内容
datanumpy ndarray(構造化または同種)
Dict、またはDataFrame,Dictには、Series、
配列、定数、またはリストのようなオブジェクト
index結果のフレームに使用するインデックス。
入力データのインデックス情報がなく
インデックスが提供されていない場合は
デフォルトでnp.arange(n)
columns結果のフレームに使用する列ラベル。
列ラベルが指定されていない場合
デフォルトはnp.arange(n)
dtypedtype、デフォルトなし 強制するデータ型。
単一のdtypeのみが許可されます。Noneの場合、推論


データフレームの作成
empty_df = pd.DataFrame()

pd.DataFrame()
これで空のデータフレームが作成されます。

カラム付きで作成するには
c_df = pd.DataFrame(columns=[1,2])

columns=[カラム名配列]
これでカラムを付けてデータフレーム作成です。
 
同じくindexを付ける場合は
c_df = pd.DataFrame(index=[1,2])
index=[インデックス名配列] とします。

辞書型からデータフレームを作成する場合は
data = {'a':[0, 1], 'b':[2, 3]}
d_df = pd.DataFrame(data=data)
d_df 
ab
002
113

data=辞書型
と引数を指定して作成します。
キーがカラム名、値は値になります。

インデックスは指定しなければ
数値の型が自動で割り振られます。

数値以外に指定したい場合は
作成時に指定するか、作成後に指定をして付け直します。

インデックスの形式をDatetimeIndexにして作成するには
date = pd.date_range('2012-1-1', '2012-1-2', freq='D')
di_df = pd.DataFrame(data, index=date)
di_df
ab
2012-01-0102
2012-01-0213

freq='D'を指定する事で日付の形式でインデックスが付けられます。
これは時系列での分析を行う際に有用な付けになるので
覚えておくと良いでしょう。

辞書型にカラムを付けて作成
data2 = {'4':11 , '6':22 , '7':33}
e_df = pd.DataFrame(list(data2.items()),columns=['column1','column2'])
e_df
column1column2
0411
1733
2622

辞書型のキーと値をデータとして利用し、
カラムを付け替えます。


numpyからデータフレーム作成

np_df = pd.DataFrame(np.random.randint(low=0, high=10, size=(5, 5)),
                     columns=['a', 'b', 'c', 'd', 'e'])
np_df
abcde
061997
132252
206629
380111
424808

numpyで5x5の数値をランダム生成し
それをデータフレームにします。
ダミーデータ作成などに便利です。

既存のデータから作成する

sklearnに付属のデータの読み込み

from sklearn.datasets import load_iris
iris = load_iris()
# データフレームに読み込み
iris_df = pd.DataFrame(iris.data, columns=iris.feature_names)
# データフレーム内容表示(上から3行)
iris_df.head(3)


sepal length (cm)
sepal width (cm)petal length (cm)petal width (cm)
05.13.51.40.2
14.93.01.40.2
24.73.21.30.2


CSVデータの読み込み

read_csv(ファイルパス , 引数)

引数

内容

sep

区切り文字 デフォルト: ‘,’ タブ '\t' セミコロン ';'

delimiter

sep の代わりに区切り文字を指定可能 デフォルト: None

header

ヘッダ行の行数を整数で指定 デフォルト: ‘infer’ ヘッダーなしは header=None

names

ヘッダ名をリストで指定 デフォルト: None 指定方法 names=('Time','Open')

index_col

行のインデックスに用いる列 デフォルト: None 数値か列名で指定

dtype

各行のデータタイプ : {‘a’: np.float64, ‘b’: np.int32} デフォルト: None

skiprows

先頭から読み込みをスキップする行数 デフォルト: None

skipfooter

末尾から読み込みをスキップする行数 デフォルト: None

nrows

読み込む行数 デフォルト: None

quotechar

ダブルクォーテーションなどでクオートされている場合のクオート文字 デフォルト: ‘”‘

escapechar

エスケープされている場合のエスケープ文字 デフォルト: None

comment

コメント行の行頭文字を指定 指定した文字で始まる行を無視 デフォルト: None

encoding

文字コード デフォルト: None 指定方法 ’utf-8′, ‘shift_jis’, ‘euc_jp’

parse_dates

datetime型で読み込むcolumn名(リストや辞書)

date_parser

parse_datesで指定したcolumnを読み込む自作関数

na_values

欠損値とする文字列(リスト)



titanic_df = pd.read_csv('data/titanic_train.csv')
titanic_df.head(3)

PassengerId

Survived

Pclass

Name

Sex

Age

SibSp

Parch

Ticket

Fare

Cabin

Embarked

0

1

0

3

Braund, Mr. Owen Harris

male

22.0

1

0

A/5 21171

7.2500

NaN

S

1

2

1

1

Cumings, Mrs. John Bradley (Florence Briggs Th...

female

38.0

1

0

PC 17599

71.2833

C85

C

2

3

1

3

Heikkinen, Miss. Laina

female

26.0

0

0

STON/O2. 3101282

7.9250

NaN

S



CSVから読み込みカラム付けとDatetimeIndex付け
fx_df = pd.read_csv('data/DAT_ASCII_USDJPY_M1_201710.csv', 
                     sep=';',
                     names=('Time','Open','High','Low','Close',''),
                     index_col='Time', 
                     parse_dates=True)
fx_df.head()

Open

High

Low

Close


Time






2017-10-01 17:00:00

112.627

112.658

112.526

112.526

0

2017-10-01 17:01:00

112.536

112.536

112.480

112.510

0

2017-10-01 17:03:00

112.512

112.532

112.510

112.510

0

2017-10-01 17:04:00

112.513

112.514

112.513

112.514

0

2017-10-01 17:05:00

112.519

112.531

112.519

112.530

0



エクセルファイルの読み込み
 
read_excel(ファイルパス)
dcf_df = pd.read_excel('data/DCFData.xlsx')
dcf_df

企業名

証券コード

会計年度

売上高

営業利益

当期純利益

支払利息(直近決算期)

支払利息(前々決算期)

有利子負債(直近決算期)

有利子負債(前々決算期)

ベータ値

減価償却費

現金同等物

有価証券(売却可能)

投資有価証券(売却可能)

株価

発行済株式数

リスクフリーレート

0

株式会社ファーストリテイリング

9983

2016

1786473000000

127292000000

48052000000

39420000000

1141000000

640457000000

388900000000

1.24

36797000000

385431000000

0

13132000000

43130

106074000

0.00082

1

豊商事

8747

2014

4237000000

-95000000

-255000000

0

0

1250000000

1118000000

0.77

244000000

5210000000

0

881000000

400





基本統計量
データフレーム名.describe()
titanic_df = pd.read_csv('data/titanic_train.csv')
titanic_df.describe()

PassengerId

Survived

Pclass

Age

SibSp

Parch

Fare

count

891.000000

891.000000

891.000000

714.000000

891.000000

891.000000

891.000000

mean

446.000000

0.383838

2.308642

29.699118

0.523008

0.381594

32.204208

std

257.353842

0.486592

0.836071

14.526497

1.102743

0.806057

49.693429

min

1.000000

0.000000

1.000000

0.420000

0.000000

0.000000

0.000000

25%

223.500000

0.000000

2.000000

NaN

0.000000

0.000000

7.910400

50%

446.000000

0.000000

3.000000

NaN

0.000000

0.000000

14.454200

75%

668.500000

1.000000

3.000000

NaN

1.000000

0.000000

31.000000

max

891.000000

1.000000

3.000000

80.000000

8.000000

6.000000

512.329200



平均値
データフレーム名.mean()
titanic_df = pd.read_csv('data/titanic_train.csv')
titanic_df.mean()
PassengerId    446.000000
Survived         0.383838
Pclass           2.308642
Age             29.699118
SibSp            0.523008
Parch            0.381594
Fare            32.204208
dtype: float64


データの加算(合計)
データフレーム名.sum()
titanic_df = pd.read_csv('data/titanic_train.csv')
titanic_df.sum()
PassengerId    397386.0000
Survived          342.0000
Pclass           2057.0000
Age             21205.1700
SibSp             466.0000
Parch             340.0000
Fare            28693.9493
dtype: float64

データ個数
データフレーム名.count()
titanic_df = pd.read_csv('data/titanic_train.csv')
titanic_df.count()
PassengerId    891
Survived       891
Pclass         891
Name           891
Sex            891
Age            714
SibSp          891
Parch          891
Ticket         891
Fare           891
Cabin          204
Embarked       889
dtype: int64

演算方向を指定する場合、列方向なら axis=0 行方向は axis=1

デフォルトはaxis=0



不偏分散
データフレーム名.var()
titanic_df.var()
PassengerId    66231.000000
Survived           0.236772
Pclass             0.699015
Age              211.019125
SibSp              1.216043
Parch              0.649728
Fare            2469.436846
dtype: float64



標本分散
データフレーム名.var(ddof=False)
titanic_df.var(ddof=False)
PassengerId    66156.666667
Survived           0.236506
Pclass             0.698231
Age              210.723580
SibSp              1.214678
Parch              0.648999
Fare            2466.665312
dtype: float64


不偏標準偏差
データフレーム名.std()
titanic_df.std()
PassengerId    257.353842
Survived         0.486592
Pclass           0.836071
Age             14.526497
SibSp            1.102743
Parch            0.806057
Fare            49.693429
dtype: float64

標本標準偏差
データフレーム名.std(ddof=False)
titanic_df.std(ddof=False)

PassengerId    257.209383
Survived         0.486319
Pclass           0.835602
Age             14.516321
SibSp            1.102124
Parch            0.805605
Fare            49.665534
dtype: float64


データサイエンティストになるには


データサイエンティストとは

最近になって出てきた職種のため明確な定義があるわけではなさそうですが

「統計解析やITスキルを用いてデータ分析を行い、ビジネス課題を解決する職務」

こんなところでしょうか

これまでにはない、新しいタイプのデータ分析を行える専門家という位置付けです




データサイエンティストが生まれた背景

従来、ビジネス課題の解決において
データから因果関係を推測するのを「マーケター」
とよばれる職種の人々が主に担務していましたが
顧客のニーズの多様化により
データ分析にも専門性やスピードが求められることとなり
データ分析だけを専門で行う人がふえてきました

しかし大量のデータを扱ったり
ビジネス課題の変化に伴い必要となるスキルや領域が増えたため
「ビジネススキル」「統計解析スキル」「ITスキル」
それらをまとめてできる人材をデータサイエンティストと呼ぶようになってきました




データサイエンティストの仕事とは

主な仕事の内容を簡単にまとめると
・課題の要件整理
・データを収集する
・データの整理、運用
・データ分析
・データの可視化
・課題解決

このようなことをやっています

「データから事業戦略にとって有益な情報を導き出しビジネスにインパクトを与える」
これが重要な役割です



データサイエンティストになるには

ではどうやったらなれるのでしょうか?
「データサイエンティスト」と呼ばれる職種は2009年ごろの登場と言われているようです
なるために必要な資格などが明確になっているわけではありません

しかし
「データサイエンティスト」を名乗るには
ある一定以上のスキルレベルがあってしかるべきだと思われます

「統計解析スキル」
「ITスキル」
「ビジネススキル」

この3つのスキル領域のうちの1つの専門家が
他の領域へスキルレベルを広げてゆくのが一般的です


人によっては
大学で「統計解析」を学び企業に入った
という人もいると思うので、そういう人は
「ITスキル」
「ビジネススキル」
を覚えていくだけで良いのですが
何もやったことのない人がなるには大変です

おそらく一番簡単なのが
「ビジネススキル」

ついで
「ITスキル」「統計解析スキル」
となるので
「ビジネススキル」
は先に覚えてしまうのが良いでしょう

1からデータサイエンティストを目指すのであれば
まずはビジネスのことを知り
課題解決へのアプローチの中で
どんな手法が必要か、その手法を行うためには
どんなスキルが必要かを学び少しづつ覚えてゆくのが
良いかと思います


データサイエンティストに必要な3つのスキル

それぞれの領域でどれだけの知識が必要なのかを詳細にまとめます


ビジネススキル」(ビジネス力)
問題課題の切り分け
ビジネス要件の整理、企画、提案
目的、ゴール設定
KPI設計
ビジネスフレームワーへの知識
分析結果への洞察力
リスク管理
マネジメント力

「ITスキル」(データエンジニアリング力)
データベースに関する知識
プログラミングに関する知識
インフラに関する知識
アーキテクトにかんする知識
SDKやAPI,ミドルウェアに関する知識
セキュリティに関する知識
データの収集、蓄積、加工、共有にかんする知識
分析環境の構築方法

「統計解析スキル」(データサイエンス力)
データの加工プロセス
データ分析の基礎知識
データの可視化方法
数学の知識
統計学の知識
機械学習の知識
モデリングに関する知識

必要な領域は常に増え続けているため
ここに書ききれないほどの量です

また一般社団法人データサイエンティスト協会では
次のように領域をまとめられて

必要なスキル内容をチェックすることもできます

これらを少しづつ網羅してゆくことで
データサイエンティストに近づくことができます







さて
行列計算を一通り覚えたところで
numpyの関数を使ってみましょう

まずはライブラリをインポート、別名をnpとしておきます
import numpy as np

sqrtは平方根を計算してくれます
引数には、数値か、数値のリスト、配列などが使えます
array_n1 = np.arange(1,10).reshape(3,3)
print(np.sqrt(25))
print(np.sqrt([2,3,4]))
print(np.sqrt(array_n1))
5.0
[ 1.41421356  1.73205081  2.        ]
[[ 1.          1.41421356  1.73205081]
 [ 2.          2.23606798  2.44948974]
 [ 2.64575131  2.82842712  3.        ]]

返ってくる値も引数と同じ型です

次に指数関数を求めます

exp = np.exp([0,1,2,3,4,5])
exp
array([   1.        ,    2.71828183,    7.3890561 ,   20.08553692,
         54.59815003,  148.4131591 ])


なお定数 e も定義されており
np.e
2.718281828459045

となります

次に対数関数は以下が定義されています
  • e が底 (Log_e(x)) の np.log(x)
  • 2 が底(Log_2(x))の np.log2(x)
  • 10 が底(Log_10(x))の np.log10(x)

それぞれこのようになります
np.log([1,2,np.e, np.e ** 2])
array([ 0.        ,  0.69314718,  1.        ,  2.        ])
np.log2([1,2,4,np.e, np.e ** 2])
array([ 0.        ,  1.        ,  2.        ,  1.44269504,  2.88539008])
np.log10([1,2,10,100,1000,np.e, np.e ** 2])
array([ 0.        ,  0.30103   ,  1.        ,  2.        ,  3.        ,
        0.43429448,  0.86858896])

三角関数も存在します

正弦関数 (sin(x), サイン)
余弦関数 (cos(x), コサイン)
正接関数 (tan(x), タンジェント) 


引数 x にはラジアンを指定する必要があります
np.sin([0,1,2,3,4])
array([ 0.        ,  0.84147098,  0.90929743,  0.14112001, -0.7568025 ])
これだと分かりづらいので
図にしてみましょう

matplotlibを使って図を作成します

%
matplotlib inline は図をjupyter notebookの中に
表示させるために必要なコードです
np.linspaceで複数値を作成し
plt.showで図を表示させます

import matplotlib.pylab as plt
%matplotlib inline

#startからendまでを個数で等分した値を返す
x = np.linspace(-5,5,100)
plt.plot(x, np.sin(x))
plt.xlabel('Angle [rad]')
plt.ylabel('sin(x)')
plt.axis('tight')
plt.show()
sin

最大値が1,最小値が-1になっています


同様にcos , tan も表示させてみます

cos
x = np.linspace(-5,5,100)
plt.plot(x, np.cos(x))
plt.xlabel('Angle [rad]')
plt.ylabel('cos(x)')
plt.axis('tight')
plt.show()
cos


tan
x = np.linspace(-3.14, 3.14, 100)
plt.plot(x, np.tan(x))
plt.xlabel('Angle [rad]')
plt.ylabel('tan(x)')
plt.axis('tight')
plt.show()
tan

タンジェントはちょっと特殊ですね

ここまでの関数の関係性をまとめてグラフにしてみます
x = np.arange(-2*np.pi, 2*np.pi, 0.25)
sin = np.sin(x)
cos = np.cos(x)
tan = np.tan(x)
exp = np.exp(x) 
log = np.log(x) 

# グラフ表示
plt.plot(x, sin,"-o",lw=2,alpha=0.7,label="sin(x)")
plt.plot(x, cos,"-o",lw=2,alpha=0.7,label="cos(x)")
plt.plot(x, tan,"-o",lw=2,alpha=0.7,label="tan(x)")
plt.plot(x, exp,"-o",lw=2,alpha=0.7,label="exp(x)")
plt.plot(x, log,"-o",lw=2,alpha=0.7,label="log(x)")

plt.xlabel("$x$", fontsize=30) # x軸のラベル
plt.ylabel("$y$", fontsize=30) # y軸のラベル
plt.xlim([-4, 4])              # x軸の範囲
plt.ylim([-4, 4])              # y軸の範囲
plt.grid()                     # グリッドの表示
plt.legend(fontsize=10)        # 凡例の表示
plt.show()                     # グラフの描画
allgraph

matplotlibによる可視化は非常に基本的なテクニックで
値を配列に格納し、グラフ化することで
データが把握しやすくなるので
ぜひ覚えておきましょう


numpyには値を生成する関数も多く存在します
まずは標準正規分布に従うランダム値を返すrandn
from numpy.random import *
import matplotlib.pyplot as plt

Rand1 = randn(10000)        # 標準正規分布で乱数を1万個生成
plt.hist(Rand1, bins=100)   # 100本のヒストグラムを作成
plt.show() 
randn

ランダムのため毎回生成される値は変わります

rand は一様分布の乱数を返します
from numpy.random import *
import matplotlib.pyplot as plt

Rand2 = rand(10000) 
plt.hist(Rand2, bins=100) 
plt.show() 
rand

rand
randn
ともに小数点で値が返ってきます

randint は整数値の配列が返ってきます
引数を調整すれば返る値の個数を変えられます
randint(1,10,10)
array([8, 3, 8, 6, 4, 1, 8, 7, 9, 2])


リストから重み付けランダム抽出

重み付けした確率でリストから取り出したい場合
random.choice で重み付け抽出が行えます
from numpy import *

jk = ["チョキ","グー","パー"]
weight = [0.1,0.2,0.7] # 重み付け
for i in range(10):
    print(random.choice(jk, p=weight)) # 指定した確率で1個を抽出
グー
パー
パー
パー
チョキ
パー
パー
グー
チョキ
パー


ランダムウォークのシミュレーションも行えます
from numpy import *
import matplotlib.pyplot as plt
rw = 1000 # 歩数 step = random.choice([-1,1],rw) # +1 or -1 をn個生成 position = cumsum(step) plt.plot(position)
rwalk


配列の計算用の関数も沢山あります
round 四捨五入
trunc 切り捨て(小数部分を除く)
floor 切り捨て(小さい側の整数に丸め)
ceil 切り上げ
fix ゼロに近い整数に丸め

sample1 = np.array([-2.7, -1.3, -0.9, 0.4, 1.5, 0.1, 2.0])
np.round(sample1)
array([-3., -1., -1.,  0.,  2.,  0.,  2.])
np.trunc(sample1)
array([-2., -1., -0.,  0.,  1.,  0.,  2.])
np.floor(sample1)
array([-3., -2., -1.,  0.,  1.,  0.,  2.])
np.ceil(sample1)
array([-2., -1., -0.,  1.,  2.,  1.,  2.])
np.fix(sample1)
array([-2., -1., -0.,  0.,  1.,  0.,  2.])

その他

abs 絶対値を返す
sign 値の符号を返す
modf 小数と整数に分けて返す
isnan NaNかどうかの判定を返す
isinf Infiniteかどうかの判定を返す
power べき乗を返す
max 最大値を返す
fmax 二つのうち大きい方を返す
min 最小値を返す
fmin 二つのうち小さい方を返す








参考資料
  • ライブドアブログ

このページのトップヘ