このシリーズでは、データ分析に必要な基礎知識からPythonによる実装までをまとめます。
今回の記事では、データ分析において重要なPythonライブラリである「Numpy」の概要と使い方について紹介します。
Google colabを使用して、簡単に実装することができますので、ぜひ最後までご覧ください。
今回の内容
・Numpyの基本操作
・行列の演算
・配列操作とブロードキャスト
- 1. Numpyとは
- 2. Numpyの基本操作
- 2.1. 配列
- 2.2. 配列の計算
- 2.3. 配列のソート(昇順・降順)
- 2.4. 最大・最小・合計・平均
- 2.5. 平方根・ネイピア指数関数
- 2.6. 積み上げの計算
- 2.7. 重複データの削除
- 3. 行列の演算
- 3.1. numpyの形状変換と行列
- 3.2. n行目・n列目を表示
- 3.3. 行列の積
- 3.4. 先頭からn番目までの配列を取り出す
- 3.5. 先頭からn番目までの要素を置換
- 3.6. 配列をcopyして別の配列を作成
- 3.7. ブールインデックス参照
- 3.8. 条件制御
- 3.9. 真偽値の判定
- 3.10. 行列の最小・最大・平均・合計の計算
- 3.11. 対角成分・対角成分の和
- 4. 配列操作とブロードキャスト
- 4.1. 再形成
- 4.2. 結合
- 4.3. ブロードキャスト
- 5. まとめ
Numpyとは
Numpyは基本的な配列処理や数値計算に用いるライブラリです。
高度で複雑な計算が可能であり、処理速度が速いことが特徴です。
Numpyの基本操作
まずはnumpyの基本操作から見ていくことにします。
Google Colab環境では、簡単に使用することができます。
import numpy as np
配列
まずは、1から10までの配列を作成してみます。
Numpyにおいて、配列はarrayオブジェクトとして構成されます。
# 配列の作成
data = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
data
array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
Numpyで扱うデータは、データの「型(type)」というものが設定されています。
データ型とは、「整数(int)」や「浮動小数(float)」などの値の種類のことです。
「整数」と「浮動小数」とでは計算量が異なるため、全体の処理速度に影響してきます。
# データの型
data.dtype
dtype('int64')
今回扱うデータは、64bit長の符号付き整数であることがわかりました。
次元数と要素数も表示してみます。
# 次元数と要素数
print('次元数:', data.ndim,'要素数:', data.size)
次元数: 1 要素数: 10
今回扱うデータは、1次元の要素数が10個ある配列であることがわかりました。
配列の計算
四則演算について、見てみましょう。
以下のように、np.arrayのそれぞれの要素に対して、演算をすることができます。
# それぞれの数字に四則演算
data = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print(data + 3)
print(data - 4)
print(data * 5)
print(data / 10)
print(data **2)
[ 4 5 6 7 8 9 10 11 12 13]
[-3 -2 -1 0 1 2 3 4 5 6]
[ 5 10 15 20 25 30 35 40 45 50]
[0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1. ]
[ 1 4 9 16 25 36 49 64 81 100]
np.array同士の要素に対して、演算をすることもできます。
# np.arrayの同士の四則演算
print(np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) + np.array([10, 9, 8, 7, 6, 5, 4, 3, 2, 1]))
print(np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) - np.array([10, 9, 8, 7, 6, 5, 4, 3, 2, 1]))
print(np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) * np.array([10, 9, 8, 7, 6, 5, 4, 3, 2, 1]))
print(np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) / np.array([10, 9, 8, 7, 6, 5, 4, 3, 2, 1]))
[11 11 11 11 11 11 11 11 11 11]
[-9 -7 -5 -3 -1 1 3 5 7 9]
[10 18 24 28 30 30 28 24 18 10]
[ 0.1 0.222 0.375 0.571 0.833 1.2 1.75 2.667 4.5 10]
配列のソート(昇順・降順)
配列の要素を並べ替えることができます。
以下の例では、昇順ソートと降順ソートを行います。
[n:m:s]のように記述すると、「n番目からm-1番目を、sずつ飛ばして取り出す」というスライス機能が実装できます。
nやmを省略したときは「すべて」という意味になるため、[::-1]とすることで「末尾から1つずつ取り出す」という意味になり、降順ソートを行うことができるようになります。
# 配列のソート(昇順・降順)
data = np.array([5, 2, 7, 4, 1, 6, 7, 3, 10, 9, 8])
print('入力データ:', data)
# 昇順ソート
data.sort()
print('昇順ソート:', data)
# 降順ソート
data[::-1].sort()
print('降順ソート:', data)
入力データ: [ 5 2 7 4 1 6 7 3 10 9 8]
昇順ソート: [ 1 2 3 4 5 6 7 7 8 9 10]
降順ソート: [10 9 8 7 7 6 5 4 3 2 1]
最大・最小・合計・平均
配列の要素の最大値、最小値、合計値、平均値を計算することができます。
# 最小、最大、合計、平均の計算
data = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
# 最小値
print('Min:', data.min())
# 最大値
print('Max:', data.max())
# 合計
print('Sum:', data.sum())
# 平均
print('mean:', data.mean())
Min: 1
Max: 10
Sum: 55
Sum: 5.5
平方根・ネイピア指数関数
配列の要素の平方根、ネイピア指数関数を計算することができます。
# ユニバーサル関数
data = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print('平方根:',np.sqrt(data))
print('ネイピア指数関数:',np.exp(data))
平方根: [1. 1.414 1.732 2. 2.236 2.449 2.646 2.828 3. 3.162]
ネイピア指数関数: [2.718e+00 7.389e+00 2.009e+01 5.460e+01 1.484e+02 4.034e+02 1.097e+03 2.981e+03 8.103e+03 2.203e+04]
積み上げの計算
cumsumにより、前から順番に足し上げていく積上演算を行うことができます。
# 積み上げ、積み上げ割合の計算
data = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
# 積み上げ
print('Cum:', data.cumsum())
# 積み上げ割合
print('Ratio:', data.cumsum() / data.sum())
Cum: [ 1 3 6 10 15 21 28 36 45 55]
Ratio: [0.018 0.055 0.109 0.182 0.273 0.382 0.509 0.655 0.818 1. ]
重複データの削除
uniqueメソッドを使用することで、重複データを削除することができます。
# 重複要素の削除
data = np.array([5,6,5,7,9,10,6,8,5,5,6,10])
print('入力',data)
print('重複削除後',np.unique(data))
入力 [ 5 6 5 7 9 10 6 8 5 5 6 10]
重複削除後 [ 5 6 7 8 9 10]
行列の演算
numpyの形状変換と行列
行列の演算を行うために、行列を作成します。
まずは以下のように配列を定義します。
np.arange(9)
array([0, 1, 2, 3, 4, 5, 6, 7, 8])
reshapeメソッドにより、3×3の行列に変換することができます。
# 形状変換で行列を作成
array1 = np.arange(9).reshape(3,3)
print(array1)
[[0 1 2]
[3 4 5]
[6 7 8]]
n行目・n列目を表示
行列のn行目・n列目を表示することができます。
# 1行目
array1[0,:]
array([0, 1, 2])
# 1列目を表示
array1[:,0]
array([0, 3, 6])
行列の積
積の計算をするため、別の行列を定義します。
array2 = np.arange(4,13).reshape(3,3)
print(array2)
[[ 4 5 6]
[ 7 8 9]
[10 11 12]]
dotメソッドにより、行列の積の計算が可能です。
# 行列の積
print(array1)
print(array2)
np.dot(array1, array2)
[[0 1 2]
[3 4 5]
[6 7 8]]
[[ 4 5 6]
[ 7 8 9]
[10 11 12]]
array([[ 27, 30, 33],
[ 90, 102, 114],
[153, 174, 195]])
行列の積ではなく、要素同士の積を計算することもできます。
# 要素どうしの積
array1 * array2
array([[ 0, 5, 12],
[21, 32, 45],
[60, 77, 96]])
先頭からn番目までの配列を取り出す
sliceメソッドにより、先頭からn番目までの配列を取り出すことができます。
以下の例では、先頭から5番目までの要素を取り出します。
# 先頭からn番目までの配列を取り出す
# 入力
in_array = np.arange(10)
# スライス
in_array_slice = in_array[0:5]
print('入力:',in_array)
print('スライス後:',in_array_slice)
入力: [0 1 2 3 4 5 6 7 8 9]
スライス後: [0 1 2 3 4]
先頭からn番目までの要素を置換
先頭からn番目までの要素を置換することができます。
以下の例では、3番目までの要素を「10」に置換しています。
# 先頭からn番目までの要素を置換
# 入力
in_array = np.arange(10)
print('入力:',in_array)
# 要素を置換
in_array[0:3] = 10
print('置換後:',in_array)
入力: [0 1 2 3 4 5 6 7 8 9]
置換後: [10 10 10 3 4 5 6 7 8 9]
配列をcopyして別の配列を作成
copyメソッドにより、元の配列をコピーして、複製することができます。
以下の例では、元の配列をコピーして、比較のために一部要素を置換しています。
# 配列をcopyして別の配列を作成
in_array = np.arange(20)
# copyして別の配列を作成
in_array_copy = np.copy(in_array)
# copyした配列の一部を置換
in_array_copy[0:7] = 20
print('入力:',in_array)
print('コピー:',in_array_copy)
入力: [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19]
コピー: [20 20 20 20 20 20 20 7 8 9 10 11 12 13 14 15 16 17 18 19]
ブールインデックス参照
bool(TrueかFalseかの真偽値)によってどのデータを取り出すかを決める、ブールインデックス参照を行うことができます。
# ブールインデックス参照
import numpy.random as random
sample_names = np.array(['a','b','c','d','a'])
random.seed(0)
data = random.randn(5,5)
print(sample_names)
print(data)
['a' 'b' 'c' 'd' 'a']
[[ 1.764 0.4 0.979 2.241 1.868]
[-0.977 0.95 -0.151 -0.103 0.411]
[ 0.144 1.454 0.761 0.122 0.444]
[ 0.334 1.494 -0.205 0.313 -0.854]
[-2.553 0.654 0.864 -0.742 2.27 ]]
この入力データについて、要素の値が「’a’」である部分だけがTrueになる結果を取り出すことができます。
sample_names == 'a'
array([ True, False, False, False, True])
Trueになる要素だけを取り出すことができます。
data[sample_names == 'a']
array([[ 1.764, 0.4 , 0.979, 2.241, 1.868],
[-2.553, 0.654, 0.864, -0.742, 2.27 ]])
条件制御
whereメソッドにより、2つのデータがあるとき、条件を満たすかどうかによって取得するデータを選択することができます。
以下の例では、AとBの配列に対して、条件データ(ブールの配列)に対応した要素を出力しています。
(条件データがTrueの場合はA、Falseの場合はBを返す)
# 条件制御
# 条件制御のためのブールの配列を作成
cond_data = np.array([True,True,False,False,True])
A= np.array([1,2,3,4,5])
B= np.array([100,200,300,400,500])
# 条件制御実施
print(np.where(cond_data,A,B))
[ 1 2 300 400 5]
表形式にすると、結果がわかりやすくなります。
pandas as pd
df = pd.DataFrame(data=[[1,2,3,4,5], [100,200,300,400,500],[np.where(cond_data,A,B)][0]], columns=[True,True,False,False,True],index = ['A','B','W'])
index | True | True | False | False | True |
---|---|---|---|---|---|
A | 1 | 2 | 3 | 4 | 5 |
B | 100 | 200 | 300 | 400 | 500 |
W | 1 | 2 | 300 | 400 | 5 |
真偽値の判定
anyやallを使うと、要素の条件判定ができます。
anyは少なくとも1つ満たすものがあればTrue、allはすべて満たす場合にTrueを返します。
# 真偽値の配列関数
cond_data = np.array([True,True,False,False,True])
print('Trueが少なくとも1つあるかどうか:',cond_data.any())
print('すべてTrueかどうか:',cond_data.all())
Trueが少なくとも1つあるかどうか: True
すべてTrueかどうか: False
行列の最小・最大・平均・合計の計算
最小、最大、平均、合計等の計算ができます。
パラメータとしてaxisを指定すると、行や列の指定もできます。
#最小、最大、平均、合計の計算
data = np.arange(9).reshape(3,3)
print(data)
print('最小値:',data.min())
print('最大値:',data.max())
print('平均:',data.mean())
print('合計:',data.sum())
# 行列を指定して合計値を求める
print('行の合計:',data.sum(axis=1))
print('列の合計:',data.sum(axis=0))
[[0 1 2]
[3 4 5]
[6 7 8]]
最小値: 0
最大値: 8
平均: 4.0
合計: 36
行の合計: [ 3 12 21]
列の合計: [ 9 12 15]
対角成分・対角成分の和
行列の対角成分と対角成分の和を計算することができます。
# 対角成分・対角成分の和
data = np.arange(9).reshape(3,3)
print(data)
print('対角成分:',np.diag(data))
print('対角成分の和:',np.trace(data)
[[0 1 2]
[3 4 5]
[6 7 8]]
対角成分: [0 4 8]
対角成分の和: 12
配列操作とブロードキャスト
再形成
Numpyでは、行列の次元を変えることを再形成と言います。
reshapeメソッドにより、再形成することができます。
data = np.arange(10)
#2行5列の行列に再形成
data = data.reshape(2,5)
print(data)
#5行2列の行列に再形成
data = data.reshape(5,2)
print(data)
[[0 1 2 3 4]
[5 6 7 8 9]]
[[0 1]
[2 3]
[4 5]
[6 7]
[8 9]]
結合
concatenateを使うと、データを行方向、列方向のそれぞれに結合できます。
array1 = np.array([[1,2,3],[4,5,6]])
array2 = np.array([[7,8,9],[10,11,12]])
print('array1',array1)
print('array2',array2)
array1
[[1 2 3]
[4 5 6]]
array2
[[ 7 8 9]
[10 11 12]]
行方向に結合する場合は、concatenateメソッドでaxis=0とするか、vstackメソッドを用います。
# 行方向に結合(axis:0)
print('---行方向に結合---')
print(np.concatenate([array1,array2],axis=0))
print(np.vstack([array1,array2]))
---行方向に結合---
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
列方向に結合する場合は、concatenateメソッドでaxis=1とするか、hstackメソッドを用います。
# 列方向に結合(axis:1)
print('---列方向に結合---')
print(np.concatenate([array1,array2],axis=1))
print(np.hstack([array1,array2]))
---列方向に結合---
[[ 1 2 3 7 8 9]
[ 4 5 6 10 11 12]]
[[ 1 2 3 7 8 9]
[ 4 5 6 10 11 12]]
ブロードキャスト
NumPy配列の二項演算ではブロードキャスト(broadcasting)という仕組みにより、それぞれの形状shapeが同じになるように自動的に変換される。
まとめ
最後までご覧いただきありがとうございました。
今回の記事では、データ分析において重要なPythonライブラリである「Numpy」の概要と使い方について紹介しました。
このシリーズでは、データ分析に必要な基礎知識からPythonによる実装の方法を紹介しておりますので、是非ご覧ください。