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

プログラミング

Pythonをある程度分かったところで
データ解析には便利なライブラリがあるので
その使い方を覚えていきましょう

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

numpyでは行列を扱うことができます
数値の行列を作ってみましょう

まずは配列を作ってarray関数で行列を作ります
my_list1 = [1,2,3,4,5]
my_array1 = np.array(my_list1)

これで1行5列の配列が出来上がります
中身を見てみましょう
my_array1
array([1, 2, 3, 4, 5])

配列と同じ要素を持った行列の出来上がりです
1次元の配列を行列にした場合は
線形代数でいう「ベクトル」になります

要素を取り出す場合
配列のように「スライス」や「添え字」が使えます
arr_1 = np.array([1,2,3,4,5,6,7,8])
arr_1[2]
3

1番目が0なので2は3番目の要素が返ります
スライスだと
arr_1[3:7]
array([4, 5, 6, 7])

また要素を代入する場合にもこの方法は使えます
arr_1[4:8]=10
arr_1
array([ 1,  2,  3,  4, 10, 10, 10, 10])

この場合、5番目から8番目までの要素に
10を代入したことになります


次に多次元配列です
新たに配列を作り、それを
さらに配列として格納し、多次元配列を作ります
my_list2 = [10,20,30,40,50]
my_lists = [my_list1,my_list2]
my_lists
[[1, 2, 3, 4, 5], [10, 20, 30, 40, 50]]


これで行列を作ります
my_array2 = np.array(my_lists)
my_array2
array([[ 1,  2,  3,  4,  5],
       [10, 20, 30, 40, 50]])


これで2行5列の行列が出来上がります
2次元以上を線形代数でいう「配列」となります

要素の取り出しの際
多次元では取り出しも多次元にしないといけません
array_2d = np.array([[1,2,3],[4,5,6],[7,8,9]])
array_2d[0]
単に添え字を使うと行が返ってきます
この場合は1行目です

個別の数値を取り出したい場合は
array_2d[0][2]
3

添え字を多次元にするか
スライスを多次元にします
array_2d[1:2,1:3]
array([[5, 6]])


作った行列の構成を確認したい場合は
shapeで確認できます
my_array2.shape
(2, 5)

格納されているデータのデータ型が知りたい場合は
dtypeで確認できます
my_array2.dtype
dtype('int64')


数値型を格納しているのでこう表示されます
行列では要素が全て同じデータ型でないといけません

特殊な行列の作り方もあります

まずは全てが0の行列
np.zeros((3,5))
array([[ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.]])

全てが1の行列の場合は
np.ones((3,5))
array([[ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.]])

空の場合は
np.empty((2,2))
array([[  0.00000000e+000,   0.00000000e+000],
       [  2.12306430e-314,   2.12307357e-314]])

この場合、数値が入っているように見えますが
中身は空です

体格成分に1、他が0になるものを単位行列といい
eye関数で作れます
np.eye(4,4)
array([[ 1.,  0.,  0.,  0.],
       [ 0.,  1.,  0.,  0.],
       [ 0.,  0.,  1.,  0.],
       [ 0.,  0.,  0.,  1.]])


range関数のように連続した数値を作ることもできます
np.arange(5,10)
array([5, 6, 7, 8, 9])

range と同じようにn個飛ばしも出来ます
np.arange(1,100,7)
array([ 1,  8, 15, 22, 29, 36, 43, 50, 57, 64, 71, 78, 85, 92, 99])

返ってくるのはarray型となります

またreshapeで行列の形を変えることもできます

arangeで作った1行の行列を4行4列の行列にするには
array_a2 = np.arange(16).reshape(4,4)
array_a2
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])


「ベクトル」「行列」の列と行を入れ替えることを転置といい
numpyでは .Tで行えます
ar3_5 = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12],[13,14,15]])
ar3_5.T
array([[ 1,  4,  7, 10, 13],
       [ 2,  5,  8, 11, 14],
       [ 3,  6,  9, 12, 15]])

5行3列の行列が転置され3行5列になります

transpose関数も.Tと同じことになります


numpyの行列同士の計算も出来ます
ar1 = np.arange(1,6)
ar2 = np.arange(2,7)
print (ar1) 
print (ar2)
print (ar1 + ar2)
print (ar1 - ar2)
[1 2 3 4 5]
[2 3 4 5 6]
[ 3  5  7  9 11]
[-1 -1 -1 -1 -1]

2つの行列の足し算では要素同士が足され
引き算では引かれます


numpyで作った行列の掛け算は
要素同士が掛け合わされます
ar3 = np.array([[1,2,3],[4,5,6]])
ar4 = np.array([[4,5,6],[7,8,9]])
print (ar3) 
print (ar4)
print (ar3 * ar4)
[[1 2 3]
 [4 5 6]]
[[4 5 6]
 [7 8 9]]
[[ 4 10 18]
 [28 40 54]]

割り算も同様で要素同士の割り算です
ar3 = np.array([[1,2,3],[4,5,6]])
ar4 = np.array([[4,5,6],[7,8,9]])
print (ar3 / ar4)
[[ 0.25        0.4         0.5       ]
 [ 0.57142857  0.625       0.66666667]]

累乗は
print (ar3 ** ar4)
[[       1       32      729]
 [   16384   390625 10077696]]



ただし、線形代数における行列の積は計算方法が違います
「ベクトル」×「スカラー」
「スカラー」×「ベクトル」
これについては特に問題なく「ベクトル」が返りますが
ar1 * 5
array([ 5, 10, 15, 20, 25])


「ベクトル」×「ベクトル」
「ベクトル」×「行列」
「行列」×「ベクトル」
「行列」×「行列」

この場合の計算方法は単純な掛け算とは違うので
注意が必要です

いわゆる内積はdot関数で求められます
ar3_1 = np.array([[1,2,3],[4,5,6],[7,8,9]])
ar3_2 = np.array([[9,6,3],[8,5,2],[7,4,1]])
print(ar3_1)
print(ar3_2)
print(np.dot(ar3_1,ar3_2))
[[1 2 3]
 [4 5 6]
 [7 8 9]]
[[9 6 3]
 [8 5 2]
 [7 4 1]]
[[ 46  28  10]
 [118  73  28]
 [190 118  46]]

単純な掛け算では
ar3_1 * ar3_2
array([[ 9, 12,  9],
       [32, 25, 12],
       [49, 32,  9]])

と返る値が違うので注意しましょう

線形代数における行列の内積は
次のように求めます
各要素の掛け算したものの足し算です
gg33

 なお「ベクトル」や「行列」の内積を求める際には
ルールがあり、行数などが等しくないと求められません
ar4_1 = np.array([1,2,3,4])
ar5_1 = np.array([1,2,3,4,5])
ar4_1.dot(ar5_1)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-69-830289c260b1> in <module>()
      1 ar4_1 = np.array([1,2,3,4])
      2 ar5_1 = np.array([1,2,3,4,5])
----> 3 ar4_1.dot(ar5_1)

ValueError: shapes (4,) and (5,) not aligned: 4 (dim 0) != 5 (dim 0)

行列の数が合わない計算はエラーになります

ar3_5 = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12],[13,14,15]])
ar5_3 = np.array([[9,6,3,7,9],[8,5,2,5,6],[7,4,1,5,5]])
ar3_5.dot(ar5_3)
array([[ 46,  28,  10,  32,  36],
       [118,  73,  28,  83,  96],
       [190, 118,  46, 134, 156],
       [262, 163,  64, 185, 216],
       [334, 208,  82, 236, 276]])

行列A
行列B
行列の積ABとするとき

Aの列数とBの行数が一致しないと
使えないことになりますので注意しましょう



参考までに


BIツールの最高峰
Tableauがver10.2になって
Pythonが使えるようになりました

使い方

1.
Tableau10.2をインストールするかアップグレード 

2.
TabPyをダウンロード

git clone git://github.com/tableau/TabPy

gitコマンドでのダウンロードになるので
gitが無い人は要git install 

3.
TabPyディレクトリに移動

cd TabPy

4. 
TabPyサーバーのインストール

sh setup.sh (Macの場合)
setup.bat (Windowsの場合)

※ここでエラーが出るかも知れませんが
普通に使えました

5.
TabPyサーバーを起動

anacondaを既にインストールしている場合
anacondaディレクトリ配下に
インストールされるみたいなので
そこの中のstartup.sh(windowsはstartup.bat)を使って起動させる

起動させるとポート9004で立ち上がる

6.
Tableau側の連携設定

外部サービス接続設定で
no title

サーバー:localhost
ポート:9004
を指定する

※外部サーバーを指定することも可能

これで環境は整ったのであとは使う側


TableauからPythonの呼び出し方

計算式を作り
SCRIPT_REAL関数等を使って呼び出す

構文
SCRIPT_REAL(
'Pythonスクリプト' , 引数指定するメジャー1 , 引数指定するメジャー2 ・・・)

引数は2個以上設定可能なため , で繋げて行く

Pythonスクリプトの部分は
Pythonの関数を定義するような形にする

引数をPython側に渡すには引数名を
_arg1 , _arg2 ・・・のような命名にする

例:
サンプルストアのデータを使って
numpyで売上、利益の相関係数を返す

1

SCRIPT_REAL( '
import numpy as np
return np.corrcoef(_arg1,_arg2)[0,1]
' , 
SUM([売上]) ,
SUM([利益]) )

2つの引数がPython側に渡り
計算値がreturnでTableau側に返ってきます

この場合単に計算式を作って配置しただけだと
式のエラー表示が出ます

これは表計算で
ディメンジョンを使用しているからです

なので式の表計算設定で
使っているディメンジョンを指定してやります
(この場合は顧客名)
フィルターに設定する場合も同様です

最後に
トヨタの株価の推移と
米ドルの価格をつかって
どれだけ相関しているかを求めてみました

toyota

期間でフィルターしており
2016年10月から現在までのトヨタの株価と
米ドルの相関性は93%ほどになりました

期間によっては相関していない部分もあったり
こういう調査をするのにプログラムコードを書かずに
マウス操作だけで出来るようになるのは
Tableauの強みかと思います

因みに
Python連携できるのは
Tableau Desktopか
Tableau Serverだけで
Public版ではできないようです

買うしか無いとかwww



 

Pythonで標準的に使われる
組み込み関数の一覧です

pythonの公式ドキュメントも参考にしてください

組み込み関数

abs()dict()help()min()setattr()
all()dir()hex()next()slice()
any()divmod()id()object()sorted()
ascii()enumerate()input()oct()staticmethod()
bin()eval()int()open()str()
bool()exec()isinstance()ord()sum()
bytearray()filter()issubclass()pow()super()
bytes()float()iter()print()tuple()
callable()format()len()property()type()
chr()frozenset()list()range()vars()
classmethod()getattr()locals()repr()zip()
compile()globals()map()reversed()__import__()
complex()hasattr()max()round() 
delattr()hash()memoryview()set() 

abs()
数の絶対値を返す
引数は整数または浮動小数点
abs(-5.23)
5.23

all()
iterable全ての要素が有ればTrueを返す
all([1,2,3])
True

any()
要素いずれかが有ればTrueを返す
any([None,None,1])
True






Pythonでは標準ライブラリの他に
いろいろなライブラリを読み込むことができます

anacondaでインストールしていれば
numpyやpandasなど
よく使われるライブラリをすぐに
読み込むことができます

読み込み方は

import モジュール名 as 別名

from モジュール名 import クラス名 as 別名

となります

as 別名は無くても良いですが
別名がないとライブラリにアクセスするのに
何度もライブラリ名を記述しないといけないため
長いライブラリ名を何度も書くことになります

別名を付けておくと記述が楽になります

特によく使われるライブラリは
略称がよく使われます

numpy np
pandas pd


早速読み込んでみましょう
今日の日付を判定してみます
from datetime import date
print date.today()
2017-01-16

小数点を切り上げ
import math
print (math.ceil(5.2332))
6

0.0~1.0までのfloatのランダム値を生成
import random
for i in range (5):
  print (random.random())

インストールされたパッケージの一覧を
見てみるには以下を実行してみることができます
import pkgutil
for m in pkgutil.iter_modules():
    print (m)
(FileFinder('//anaconda/lib/python3.5'), '__future__', False)
(FileFinder('//anaconda/lib/python3.5'), '_bootlocale', False)
(FileFinder('//anaconda/lib/python3.5'), '_collections_abc', False)・・・以下略

anacondaを使うとかなりの数がインストールされています

標準ライブラリや
その他のライブラリについては
おいおい紹介してゆきます

自作ライブラリの読み込み方

外部ライブラリでなく
自分で作ったものを読み込みこみたい場合は

まず自作のライブラリを用意します
pythonのpyファイルとして作成し

balss.py
def balss(val):
    print ('バルス!!' * val)

これをjupyter notebook のrootディレクトリに保存します
macの場合はデフォルト設定だと /Users/ユーザー名

jupyter上でどこに今いるかが分からない場合は
!pwd
と打って確認してみましょう

使う場合は「.py」を抜いたパッケージ名前でimportします
import balss
balss.balss(5)
バルス!!バルス!!バルス!!バルス!!バルス!!

これでよく使う処理などを
別ファイルに書き出しておけば
いつでも呼び出すことができます

再利用したい場合に使いましょう

自分で作った関数を定義して使うこともできます

基本構文は

def 関数名(引数): 
処理

引数に使う変数は無くても問題なし
関数名には英大小文字とアンダースコアが使えます

それでは作ってみましょう
引数指定した数値までの
フィボナッチ数を出力する関数を作ります
def fib(n): 
    a, b = 0, 1
    while a < n:
        print(a, end=' ')
        a, b = b, a+b
    print()
これを実行するには関数名(引数)とします
fib(100)
0 1 1 2 3 5 8 13 21 34 55 89 

引数を変えることで結果を変えることができます
ただしこれでは必ずprintされてしまうので
使い勝手が悪いです

結果を変数にするためには return を使って
戻り値を返すようにします
def fib_b(n): 
    a, b = 0, 1
    result = []
    while a < n:
        result.append(a)
        a, b = b, a+b
    return result

print(fib_b(20))
[0, 1, 1, 2, 3, 5, 8, 13]


これで関数の結果がリストになって返ってきます
通常は処理をまとめるために使うものなので
戻り値を返すようにするのが良いでしょう

ラムダ式

pythonのコードの中で
関数名をつけずに変数として関数を記述できます
書き方は

変数名 = lambda 変数名 : 返り値

少しややこしいですが
これで処理を簡潔に書くこともできます
f = lambda a, b : a + b
print(f(3,5))
8

こうした場合、変数名として一度定義しているので
同じ処理として繰り返し使うことができます



このページのトップヘ