# chapter 2
# マジックコマンドのクリックリファレンス
%quickref
# numpy拡張マジックコマンド
%precision 3
# matplotlib拡張マジックコマンド
%matplotlib inline
# 計算モジュール インポート
import numpy as np
import numpy.random as random
import scipy as sp
import pandas as pd
from pandas import Series, DataFrame
# 可視化モジュール インポート
import matplotlib.pyplot as plt
import matplotlib as mpl
import seaborn as sns
%matplotlib inline
# 少数第三位まで表示
%precision 3
# numpy
import numpy as np
ar = np.array([1,2,3,4,5])
print(ar)
print(ar.dtype)
print(ar.ndim) #次元数
print(ar.size) #要素数
# 掛け算ができる listとは違って数学的
ar # array([1, 2, 3, 4, 5])
ar * 2 # array([ 2, 4, 6, 8, 10])
ar / 2 # array([0.5, 1. , 1.5, 2. , 2.5])
ar **2 # array([ 1, 4, 9, 16, 25], dtype=int32)
# sort
ar_before = [3,7,2,5,6,7,2]
ar_after = ar_before.sort()
print(ar_before)#[2, 2, 3, 5, 6, 7, 7]
print(ar_after) #None
# 破壊的:元のar_beforeが書き換わってしまった。
# 降順で並び替える方法
ar_before = [3,7,2,5,6,7,2]
ar_before[::-1].sort()
print(ar_before)
# できない・・・
# メソドsortは破壊的。 嫌い
ar_before = [3,7,2,5,6,7,2]
ar_before.sort() # sortメソド 昇順
print(ar_before)
ar_before = [3,7,2,5,6,7,2]
ar_before.sort(reverse=True)# sortメソド reverse=Trueで降順
print(ar_before)
# 関数sortedは破壊的でない。 おすすめ。
ar_before = [3,7,2,5,6,7,2]
ar_after = sorted(ar_before)
print(ar_after)
print(ar_before) # 元のリストは破壊されていない。
ar_before = [3,7,2,5,6,7,2]
ar_after = sorted(ar_before, reverse=True) # reverse=Trueで降順
print(ar_after)
print(ar_before) # 元のリストは破壊されていない。
# メソド max min sum cumsum
ar = np.array([1,2,3,4,5]) # listではむり
print(ar.max()) # 5
print(ar.min())
print(ar.sum())
print(ar.cumsum())
# 累積割合
ar.cumsum() / ar.sum()
# 乱数
import numpy.random as random
random.seed(0)
rand_data = random.random(100)
print(rand_data)
print(rand_data.max(), rand_data.min(), rand_data.sum()/100)
# 正規分布 平均0 分散1
dist_normal = random.randn(10)
print(dist_normal)
# データの抽出 random.choice() 重複あり
random.choice(rand_data, 5)
# 重複なし replace = False
random.choice(rand_data, 5, replace=False)
# 行列
ar = np.arange(9) # array([0, 1, 2, 3, 4, 5, 6, 7, 8])
matrix = np.arange(9).reshape(3, 3)
'''
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
'''
# 行列の抽出
ar[2:7] # array([2, 3, 4, 5, 6])
matrix[0,1] # 1
matrix[0,:] # array([0, 1, 2])
# 行列の演算
matrix1 =np.arange(9).reshape(3,3)
matrix2 =np.arange(9).reshape(3,3)
# ドット積
np.dot(matrix1, matrix2)
'''
array([[ 15, 18, 21],
[ 42, 54, 66],
[ 69, 90, 111]]
'''
# 要素同士の積
matrix1 * matrix2
'''
array([[ 0, 1, 4],
[ 9, 16, 25],
[36, 49, 64]])
'''
# ゼロ行列
np.zeros((3,4), np.int64) # サイズをタプルで入れる必要がある
# 1行列
np.ones((3,4), np.int64)
# 練習問題
ar = np.arange(51)
print(np.sum(ar))
# 練習問題
data = random.randn(10)
print(data.max(), data.min(), data.sum())
# 練習問題
(np.ones((5,5)) * 3 ) ** 2
# chapter 2-3 scipy
# 線形代数モジュール
import scipy.linalg as linarg
# 最適化計算用の関数
from scipy.optimize import minimize_scalar
# 行列式 と 逆行列
matrix = np.array([[1,-1,-1],[-1,1,-1],[-1,-1,1]])
'''
array([[ 1, -1, -1],
[-1, 1, -1],
[-1, -1, 1]])
'''
# 行列式det を求める
linarg.det(matrix) # -4.000
# 逆行列invers を求める
linarg.inv(matrix)
'''
array([[ 0. , -0.5, -0.5],
[-0.5, -0. , -0.5],
[-0.5, -0.5, 0. ]])
'''
# 確認する
matrix.dot(linarg.inv(matrix))
'''単位行列になるはず
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
'''
linarg.inv(matrix).dot(matrix)
'''
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
'''
# 固有値 と 固有ベクトル
eig_value, eig_vector = linarg.eig(matrix)
print('固有値:\n', eig_value)
print('固有ベクトル:\n',eig_vector)
# 最適化計算 ニュートン法
from scipy.optimize import newton
# 関数定義
def func1(x):
return x**2 + 2*x + 1
# 解く
newton(func1,0) # -1.000 0は [ 0 = x**2 + 2*x + 1 ] を解くという意味
# 最小値を求める
minimize_scalar(func1,method='brent')
'''
fun: 0.0
nfev: 9
nit: 4
success: True
x: -1.0000000000000002
'''
# 練習
matrix_a = ([[1,2,3],[1,3,2],[3,1,2]])
linarg.det(matrix_a) # 行列式 -12.000
linarg.inv(matrix_a) # 逆行列
'''
array([[-0.333, 0.083, 0.417],
[-0.333, 0.583, -0.083],
[ 0.667, -0.417, -0.083]])
'''
eig_value, eig_vector = linarg.eig(matrix_a)
print(eig_value) # 固有値 [ 6. +0.j -1.414+0.j 1.414+0.j]
print(eig_vector)# 固有ベクトル
'''
[[-0.577 -0.722 0.16 ]
[-0.577 -0.143 -0.811]
[-0.577 0.677 0.563]]
'''
# 練習 ニュートン法
def func(x):
return (x**3 + 2*x +1)
newton(func,0) # -0.453
# chapter 2-4 pandas
from pandas import Series, DataFrame
data = pd.Series([0,10,20,30,40,50])
data
# indexをつける
index = ['a','b','c','d','e','f']
data = pd.Series([0,10,20,30,40,50], index=index)
data
data.values # array([ 0, 10, 20, 30, 40, 50], dtype=int64)
data.index # Index(['a', 'b', 'c', 'd', 'e', 'f'], dtype='object')
# DataFrame
# ディクショナリを定義
dic = {'id':[100,101,102,103], 'name':['aaa','bbb','ccc','ddd'],'age':[5,3,7,8]}
dic
# ディクショナリをDataFrameに変換
df = pd.DataFrame(dic)
df
# index後付
df.index =['a','b','c','d']
df
# 任意のcolumnを抽出
df.name
'''
a aaa
b bbb
c ccc
d ddd
Name: name, dtype: object
'''
df['name'] # でも同じ
# 複数のときはリストで渡すこと
df[['name', 'age']]
# 転置
df.T
# データの抽出 フィルター
df
# 列を抽出して5のものを調べる boolで出力される
df['age'] == 5
# このboolを利用してTrue部分を抽出する
df[df['age'] == 5]
# 複数条件で抽出するとき isin
df['age']
df['age'].isin([3,7])
# このboolを利用して
df[df['age'].isin([3,7])]
# 練習:age 5 以上を抽出してみる
df['age'] >= 5
df[df['age'] >= 5]
# データの結合と削除
# age 列axis=1 を 削除drop
df.drop(['age'], axis=1)
df # 元データからageが消えたわけではない df = df.drop([ ].axis=1) または パラメータinplace = Trueで置き換える
# index b,c を削除dorp axis=0
df.drop(['b', 'c'], axis = 0)
# データの結合 merge
df1=pd.DataFrame({'id':[100,101,102,103], 'name':['aaa','bbb','ccc','ddd']})
df2=pd.DataFrame({'id':[100,101,102,103], 'age':[5,7,9,3]})
df3=pd.DataFrame({'id':[100,101,102,103], 'sex':['male','male','female','female']})
# 共通のキー 'id' を自動的に見つけてマージしてくれる
df1_2 = pd.merge(df1, df2)
df1_2_3 = pd.merge(df1_2, df3)
df1_2_3
# 集計
# 性別毎に年齢の平均値を集計する
df1_2_3.groupby('sex')['age'].mean()
# 性別毎に年齢の最大値を集計する
df1_2_3.groupby('sex')['age'].max()
# ソート
# データ作成
df = df1_2_3
df.index = ['b','a','c','d']
df
# ソートインデックス
df.sort_index()
# ソート age
df.age.sort_values()
# 欠損データ nunの判定
df1=pd.DataFrame({'id':[100,101,102,103], 'data':[435,432,24,64]})
df = df.merge(df1)
df
# female を抽出する
df.isin(['female'])
# dataをnunにする
df['data'] = np.nan
df
# nan を isnullメソドで調べる
df.isnull()
# 個数を数える
df.isnull().sum()
# 練習:
data = {'ID':['1','2','3','4','5'],
'sex':['F','F','M','M','F'],
'Money':[1000, 2000, 500, 300, 700],
'Name':['Saito', 'Horie', 'Kondo', 'Kawada', 'Matsubara']}
df = pd.DataFrame(data)
df
# 性別毎の平均Moneyを求める
df.groupby(['sex'])['Money'].mean()
# IDでマージして Money Math English の平均を求める
data2 = {'ID':['3','4','7'],
'Math':[60,30,40],
'English':[80,20,30]}
df2 = pd.DataFrame(data2)
df2
df = df.merge(df2)
df
print(df.Money.mean())
print(df.Math.mean())
print(df.English.mean())
# chapter 2-5 matplotlib seaborn
import matplotlib as mpl
import seaborn as sbn
import matplotlib.pyplot as plt
%matplotlib inline
# サンプルデータの作成
import numpy.random as random
random.seed(0)
x = random.randn(30)
y = np.sin(x) + np.random.randn(30)
# 折れ線グラフ(線を消している)
plt.figure(figsize=(20,6))
plt.plot(x,y, 'o')
plt.grid(True)
# 散布図
plt.figure(figsize=(20,6))
plt.scatter(x,y)
plt.title('title', fontsize=24)
plt.xlabel('xlabel', fontsize=18)
plt.ylabel('ylabel', fontsize=18)
plt.grid(True)
# 連続した線グラフ
random.seed(1)
x = np.arange(1000)
y = np.random.randn(1000).cumsum()
plt.figure(figsize=(20,6))
plt.plot(x, y, label='label_a')
plt.grid(True)
plt.legend(loc='best')
plt.show()
# グラフを分割 subplot
plt.figure(figsize=(20, 6))
# 2行1列配置
# 1行目のグラフ
plt.subplot(2,1,1)
# 2行目のグラフ
plt.subplot(2,1,2)
# 関数グラフ
def func1(x):
return (x**2 + 2*x + 1)
x = np.arange(-10,10)
plt.figure(figsize=(20,6))
plt.plot(x, func1(x))
plt.grid(True)
# ヒストグラム
random.seed(2)
plt.figure(figsize=(20,6))
# 対象データ 分割個数 範囲
data = np.random.randn(10**5) * 10 + 50
plt.hist(data, bins=60, range = (0,100))
plt.grid(True)
# ?plt.hist
# 練習
from scipy.optimize import newton
def func(x):
return (5*x + 3)
x = np.arange(-10,10,0.1)
y = func(x)
plt.figure(figsize=(20,6))
plt.plot(x, y, 'o')
plt.xlim(-10, 10)
plt.grid(True)
newton(func, 0)
# 練習
x = np.arange(-10, 10, 0.1)
y1 = np.sin(x)
y2 = np.cos(x)
plt.figure(figsize=(20, 6))
plt.xlim(-10, 10)
plt.plot(x, y1, label='sin(x)')
plt.plot(x, y2, label='cos(x)')
plt.legend(loc='best')
# 練習
import numpy.random as random
random.seed(0)
x1 = random.uniform(0, 1, 100)
random.seed(1)
x2 = random.uniform(0, 1, 1000)
random.seed(0)
x3 = random.uniform(0, 1, 10000)
random.seed(1)
x4 = random.uniform(0, 1, 100000)
plt.figure(figsize=(20,10))
plt.subplot(4,1,1)
plt.hist(x1,bins=20, range = (0, 1))
plt.subplot(4,1,2)
plt.hist(x2,bins=20, range = (0, 1))
plt.subplot(4,1,3)
plt.hist(x3,bins=20, range = (0, 1))
plt.subplot(4,1,4)
plt.hist(x4,bins=20, range = (0, 1))
# 練習 モンテカルロ法 乱数を使って円周率を求める
import numpy.random as random
import math
random.seed(0)
x = random.uniform(0, 1, 10000)
y = random.uniform(0, 1, 10000)
plt.plot(x, y, 'o')
# 原点からの距離 ユーグリッドノルム (x**2 + y**2)**(1/2)
li = []
li_hypot = []
for x_elm, y_elm in zip(x, y):
li.append((x_elm, y_elm))
li_hypot.append(math.hypot(x_elm, y_elm))
li = np.array(li)
li_hypot = np.array(li_hypot)
type(li_hypot)
li_hypot < 1 # bool
print('円の中に入る個数:', sum(li_hypot < 1))
print('割合:', sum(li_hypot < 1) / len(li_hypot))
df = pd.DataFrame(li)
df.columns = ['x','y']
df2 = pd.DataFrame(li_hypot)
df = pd.merge(df, df2, on = df.index)
df.keys()
del df['key_0']
df.columns = ['x','y','hypot']
# 抽出
df_inner = df[df['hypot'] < 1]
df_inner
df_outer = df[df['hypot'] >= 1]
df_outer
plt.figure(figsize=(10,4))
plt.subplot(1,2,1)
plt.plot(df_inner['x'], df_inner['y'], 'o')
plt.subplot(1,2,2)
plt.plot(df_outer['x'], df_outer['y'], 'x')
# 半径1の円の面積はπ
# 当該グラフでは 1/4 の面積なのでπ/4 のはず
# グラフの正方形は1辺が1なので面積は1
print('円の中に入る個数:', sum(li_hypot < 1))
print('割合:', sum(li_hypot < 1) / len(li_hypot))
# だったので 割合 =π/4 : 1 のはず
# π/4 = 割合 → π = 4 * 割合 より
pai = 4 * (sum(li_hypot < 1) / len(li_hypot))
pai