LoginSignup
25
21

More than 1 year has passed since last update.

【完全版】NumPyの使い方を徹底解説【機械学習】

Last updated at Posted at 2022-10-16

NumPy(ナムパイ)とは、高速計算処理を得意とするPythonのライブラリです。


機械学習をPythonで行う場合は、NumPyをよく使います。

本記事では、NumPyの基礎的な文法を徹底解説します。



ベクトルや行列の概念の説明から、基礎文法の図解まで、Python初心者でも挫折せずに学ぶことができます。



是非ブックマークして、何度も見返すことをオススメします。

この記事を執筆した筆者について

データサイエンス関連を学習中の若手SEです。

機械学習、データ分析といったデータサイエンスに関する記事を投稿中ですので、こちらも合わせて御覧ください。

■ブログ:https://datascience-lab.sakura.ne.jp
■Youtube:https://www.youtube.com/channel/UCwlSTr8FIuNnaNPZIzDghAA
■Twitter:https://twitter.com/juri_engineer

なぜ機械学習でNumPyを使うの?

NumPyを使う理由は、大量のデータを計算するのに適しているからです。

機械学習はデータ量が多いほど精度が上がりやすいので、データを処理する速度は非常に大切なポイントです。


NumPyは機械学習に適したライブラリなのです。

なぜ計算が早いのか

NumPyはベクトル演算を使うことで、ループをせずに配列や行列の計算ができます。

ベクトルや行列、配列は、後ほど解説します。

次元とは

NumPyの文法に入る前に、基本的な概念・用語について確認しておきましょう。

NumPyでは「次元」という言葉がよくでてきます。

次元とは、空間の広がりを表します。

・一次元というのは、軸が1本、つまり、点と直線のみで表現されます。
・二次元は、軸が2本なので、を表します。
・三次元は、軸が3本なので、立体を表します。






ベクトルと行列

ベクトルとは

NumPyでいうベクトルとは、数字や文字列が複数連なったものです

ベクトルは、配列の一種です。
列が1列なので、1次元配列です。



ベクトルの長さは、要素数です。

上記の例にあるベクトルAは、要素数が5なので、長さ=5です。




行列とは

行列とは、行と列からできた数字や文字列の集まりです。

行と列からなる行列は、二次元配列とも呼ばれます。



それぞれのデータを、要素と呼びます。



行列は、大文字のアルファベットを使って表現します。


上記の例では、行列Aと名付けられています。

行と列の覚え方は、下記がおすすめです。

漢字で考えるとわかりやすいです。



行と列の覚え方




行列はどんなサイズも取ることができ、一般的にm×nの行列Aと表現します。

一方で、特定の要素は小文字で表現されます。(例:a22

例えば、aijは、i行j列にある要素を表現できます。

スカラー

1,2,3...のように、数字単体を表します。次元がありません。

0次元です!



配列とは(ndarray配列)

配列とは、複数の要素を入れておくための入れ物のイメージです。

NumPyで提供される配列は、ndarrayと呼ばれます。



配列は複数のデータ型の要素を格納できるのに対し、ndarray配列は一種類のデータ型しか格納できません。



ベクトルは一次元、行列は二次元ですが、ベクトルも行列もndarray配列の一種です。



リスト・タプル・ディクショナリとベクトルの違い

pythonで使う代表的なデータ型として、リストやタプル、ディクショナリ(辞書型)があるけど、ベクトルとどういった点が違うのでしょう?



ベクトルと、リスト・タプル・ディクショナリとの違いは、数字・文字列などの複数のデータ型を1つのリストに格納できるかどうかです。


  • ベクトル:要素のデータ型は1種類のみ
  • リスト・タプル・ディクショナリ:複数のデータ型の要素を入れられる



リスト

リストとは、要素を並べたものです。

list = [5,10,15,20]
list

>> 実行結果
[5, 10, 15, 20]



ベクトルとの違いは、数字・文字列などの複数のデータ型を1つのリストに格納できるかどうかです。


#リストは複数のデータ型を格納できる
list2 = [1,"apple",4.5]
list2



>>実行結果
[1, "apple", 4.5]





タプル

タプルも、リストと同様に要素を並べたものです。

定義する時に、リストは角括弧で囲むのに対し、タプルは丸括弧で囲みます。

#タプルの定義
tuple = (1,2,3)
tuple

>>実行結果
(1, 2, 3)




リストと異なり、タプルは一度定義すると、上書きや追加をすることができません。

#タプルは上書きできない
tuple[1] = 10

>>実行結果
TypeError: "tuple" object does not support item assignment




ベクトルとタプルの違いは、リストと同様、複数のデータ型を入れられるかどうかです。


ディクショナリ

ディクショナリ(辞書型)とは、keyとvalueをセットで格納できるデータ型です。

#辞書型を定義
dict = {"No.1":"apple", "No.2":"orange", "No.3":"banana"}
dict


>>実行結果
{"No.1": "apple", "No.2": "orange", "No.3": "banana"}



リストと同様に、複数の異なるデータ型を格納することができます。





NumPyの基本的な使い方

※編集途中(コード部分)。完成版は、下記リンクをご参照ください※
https://datascience-lab.sakura.ne.jp/numpy/

インポート

まずは、NumPyをインポートすることで、手元のPythonファイルでNumPyを使えるようにしましょう。

一般的に、NumPyはnpとしてインポートします。

#NumPyをimport
import numpy as np



ndarray配列の作り方

ベクトルの作り方

ndarray配列を作る時は、NumPyに含まれる関数arrayを使います。

事前に作ったリストをndarray配列に変換するイメージです。



ここでは、ベクトルを作成します。

#リストの作成(一次元)
data = [1,2,3,4]
#array関数でndarray配列にする
a = np.array(data)
a
>>実行結果
array([1, 2, 3, 4])



行列(マトリックス)の作り方

行列もndarray配列の一種です。


そのため、ベクトルを生成した時と同様、array関数を使います。

#1リストが1行になる
data2 = ([1,2,3,4],
         [5,6,7,8],
         [9,10,11,12])
#array関数で行列にする
b = np.array(data2)
b
>>実行結果
array([[ 1,  2,  3,  4],
[ 5,  6,  7,  8],
[ 9, 10, 11, 12]])



初期化配列を作る【zeros関数】

全ての要素が0のベクトルや行列を作りたい場合は、zeros関数を使います。

0で初期化されているベクトルや行列がほしい時に使います。



#1次元配列(ベクトル)
zeros = np.zeros(10) 
zeros
>>実行結果
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])



#2次元配列はタプルで行数・列数をそれぞれ指定する
zeros2 = np.zeros((4,5))
zeros2
>>実行結果
array([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]])



全ての要素が1の配列を作る【ones関数】

全ての要素が1のベクトルや行列を作るときは、onesを使いましょう。

#全ての要素が1のベクトルを作る
np.ones(4)
>>実行結果
array([1., 1., 1., 1.])




#全ての要素が1の行列を作る
np.ones((3,5))
>>実行結果
array([[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.]])





全ての要素を指定した数でベクトルや行列を作る【full関数】

np.full(5,3)
>>実行結果
array([3, 3, 3, 3, 3])




対角線上の要素を1にした行列を作る【eye関数】

行列の対角線上の要素を1、他の要素を0にした行列を作る時は、eye関数を使います。

np.eye(4)
>>実行結果
array([[1., 0., 0., 0.],
[0., 1., 0., 0.],
[0., 0., 1., 0.],
[0., 0., 0., 1.]])




等間隔の行列を作る【arange関数】

等間隔の要素が格納されたベクトルを作る時は、arange関数を使います。

#arange(終わりの数字)
np.arange(5)
>>実行結果
array([0, 1, 2, 3, 4])



#arange(始める数字, 終わりの数字)
np.arange(5,10)
>>実行結果
array([5, 6, 7, 8, 9])



#arange(始める数字, 終わりの数字, 間の数字)
np.arange(5,50,3)
>>実行結果
array([ 5,  8, 11, 14, 17, 20, 23, 26, 29, 32, 35, 38, 41, 44, 47])




ベクトルを行列にしたい場合は、reshape関数を使います。

#行列にする
np.arange(5,50,3).reshape(5,3)
>>実行結果
array([[ 5,  8, 11],
[14, 17, 20],
[23, 26, 29],
[32, 35, 38],
[41, 44, 47]])



中身を調べる

配列の形状を調べる

各次元ごとの要素数を表示したい場合は、属性shapeをつかいます。

ndarray配列名.shapeで、ベクトルや行列のサイズを表示してくれます。

#ndarray配列の形状を調べる
a.shape
>>実行結果
(4,)



aは一次元配列です。

一次元配列は軸が列のみなので、4は要素数を表すことになりますね。


4×1の行列とも言えます。


shapeは、引数にndarray配列名を指定する方法でも使えます

np.shape(a)


行列の形状も調べることができます。



下記の例では、3×4の行列であることがわかりました。

#行列の形状もわかる
b.shape
>>実行結果
(3, 4)




次元を確認する

ndarray配列が何次元なのかを確認したい場合は、属性ndimを使います。


ndarray配列aは一次元なので、実行結果は1となります。

#次元を確認する
a.ndim
>>実行結果
1





行列bは二次元のため、実行結果は2になりました。

#行列は2次元
b.ndim
>>実行
2




引数にndarray配列を指定する方法でも、同様の結果が得られます。

#引数に指定する方法でも使える
np.ndim(a)





データ型を確認する

ndarray配列名.dtypeで、ndarray配列に格納されている要素のデータ型を確認できます。

#データ型の確認
a.dtype
>>実行結果
dtype('int64')




行列でも、同様にデータ型が確認できます。

b.dtype
>>実行結果
dtype('int64')



intの後に64という数字が入っていますが、これはビット数を表します。

ビット数とは、データのサイズで、数字が大きいほどデータも大きいことを表します。

ビット数が大きいと、計算の処理速度が遅くなります。




要素が文字列なら、unicode型になります。

data = ["apple", "banana", "orange"]
c = np.array(data)
c.dtype
>>実行結果
dtype('<U6')




要素が小数なら、float型になります。

#要素が小数なら、float型
data = [0.1,0.04,6.9]
d = np.array(data)



要素数を調べる

全ての要素数を確認するときは、属性sizeを使います。

#要素数の確認
a.size
>>実行結果
4




行列のときも同様に確認できます。

b.size
>>実行結果
12




統計量

平均

平均は、mean関数を使うことで簡単に算出できます。

np.mean(a)
>>実行結果
2.5


引数でaxis属性を指定することで、行ごと・列ごとの算出も可能です。

#行列の行ごとの平均を知りたい場合
np.mean(b,axis=1)
>>実行結果
array([ 2.5,  6.5, 10.5])


#行列の列ごとの平均を知りたい場合
np.mean(b, axis=0)
>>実行結果
array([5., 6., 7., 8.])



分散

分散は、var関数を使いましょう。

np.var(a)
>>実行結果
1.25

標準偏差

標準偏差の算出は、std関数を使います。

np.std(a)
>>実行結果
1.118033988749895



標準偏差や分散がどのような値なのか、何が違うのかについてはこちらの記事で解説しています。


ぜひご参照下さい。

[kanren postid ="567"]




最大・最小

ndarray配列の要素の最大値・最小値を出す場合は、maxとmin関数を使います。

np.max(a)
>>実行結果
4



np.min(a)
>>実行結果
1





行列から抽出する


一次元配列にする

行列を一次元配列にする時は、ravel関数を使います。

ravel関数は、要素を1つずつ取り出したいときに使います。



np.ravel(b)
>array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12])




行番号・列番号を指定して抽出する

ndarray配列名[行番号,列番号]と指定することで、指定した要素を取り出せます。

b[1,1]
>>実行結果
6



行番号・列番号は0から始まるので、注意しましょう。

b[0,3]
>>実行結果
4



ベクトルでも番号での指定が可能です。

a[2]
>>実行結果
3




最後の要素を指定したい場合は、-1で指定可能です。


a[-1]
>>実行結果
4





スライスで抽出する

スライスとは、複数要素を取得する場合に範囲選択することです。


スライスには、「:(コロン)」を使います。


#ベクトルの1番目〜2番目を抽出する
a[1:3]
>>実行結果
array([2, 3])


#0行目〜1行目、1列目〜2列目
b[0:2,1:3]
>>実行結果
array([[2, 3],
[6, 7]])





「:(コロン)」は単体で使うと、全選択を意味します。

#行を全選択し、列は列番号で指定
b[:,2]
>>実行結果
array([ 3,  7, 11])


#行は行番号で指定し、列を全選択で指定
b[1,:]
>>実行結果
array([5, 6, 7, 8])



条件で抽出する

条件指定で配列や行列の要素を取得する場合は、比較演算子を使います。


b>4
>>実行結果
array([[False, False, False, False],
[ True,  True,  True,  True],
[ True,  True,  True,  True]])


比較演算子は、次の4種類が使えます。

比較演算子 意味
配列 > x x よりも大きい要素を取得する
配列 < x x よりも小さい要素を取得する
配列 >= x x と等しいか大きい要素を取得する
配列 <= x x と等しいか小さい要素を取得する



行列を操作する

ベクトル同士の計算

ベクトル同士の計算について学習しましょう。

計算は通常の演算子を使います。

ベクトルの計算方法は、同じ場所にある要素を足したり、引いたりします。


# 計算用の配列を作成
array1 = np.array([1,2,3,4,5,6])
array2 = np.array([2,4,6,8,10,12])
#和
array1 + array2
>>実行結果
array([ 3,  6,  9, 12, 15, 18])




和だけでなく、他の演算でも横方向に計算します

#差
array2 - array1
>>実行結果
array([1, 2, 3, 4, 5, 6])



#積
array1 * array2
>>実行結果
array([ 2,  8, 18, 32, 50, 72])



#商
array2 / array1
>>実行結果
array([2., 2., 2., 2., 2., 2.])




行列同士の計算

行列の演算も配列と同様に、同じ場所にある要素を足したり、引いたりします。



#行列を作成
matrix1 = np.array([[1,2,3,4,5,6],
                    [2,4,6,8,10,12],
                    [3,6,9,12,15,18]])
matrix2 = np.array([[4,8,12,16,20,24],
                    [5,10,15,20,25,30],
                    [6,12,18,24,30,36]])
#和
matrix1 + matrix2
>>実行結果
array([[ 5, 10, 15, 20, 25, 30],
[ 7, 14, 21, 28, 35, 42],
[ 9, 18, 27, 36, 45, 54]])


#差
matrix2 - matrix1
>>実行結果
array([[ 3,  6,  9, 12, 15, 18],
[ 3,  6,  9, 12, 15, 18],
[ 3,  6,  9, 12, 15, 18]])



#積
matrix1 * matrix2
>>実行結果
array([[  4,  16,  36,  64, 100, 144],
[ 10,  40,  90, 160, 250, 360],
[ 18,  72, 162, 288, 450, 648]])



#商
matrix2 / matrix1
>>実行結果
array([[4. , 4. , 4. , 4. , 4. , 4. ],
[2.5, 2.5, 2.5, 2.5, 2.5, 2.5],
[2. , 2. , 2. , 2. , 2. , 2. ]])













転置

転置とは、行と列を入れ替えることです。

転置のイメージ



#行と列を入れ替える
b.T
>>実行結果
array([[ 1,  5,  9],
[ 2,  6, 10],
[ 3,  7, 11],
[ 4,  8, 12]])




ただし、ベクトル(一次元配列)は行と列がないため、Tでは転置できません。

#一次元配列は行と列がないため、Tでは転置できない
a.T
>>実行結果
array([1, 2, 3, 4])




行数と列数を指定して形を変える

reshape関数を使うと、行列の行数と列数を変更したり、ベクトルを行列に変更したりすることができます。



#3×4の行列を2×6に変更する
b.reshape(2,6)
>>実行結果
array([[ 1,  2,  3,  4,  5,  6],
[ 7,  8,  9, 10, 11, 12]])


reshape関数を使うと、一次元配列も転置することができます。

もちろん、行列に変換することもできます。



#ベクトルを転置する。(縦1列にする)
a.reshape(4,1)
>>実行結果
array([[1],
[2],
[3],
[4]])



#ベクトルaを2×2の行列に変える
a.reshape(2,2)
>>実行結果
array([[1, 2],
[3, 4]])




ブロードキャスト

ブロードキャストとは、ndarray配列の大きさ・次元が違う場合、自動的に要素をコピーして大きさを揃える機能です。



例えば、ベクトル(一次元配列)と行列(二次元配列)や、スカラー(0次元配列)とベクトルの計算をする際などに効果的です。


#ブロードキャスト(行列と配列の和)
a + b
>>実行結果
array([[ 2,  4,  6,  8],
[ 6,  8, 10, 12],
[10, 12, 14, 16]])



#スカラー(0次元配列)と行列(2次元配列)
5 * b
>>実行結果
array([[ 5, 10, 15, 20],
[25, 30, 35, 40],
[45, 50, 55, 60]])



配列の結合・分割

縦方向にndarray配列を結合する時は、vstack関数を使います。

各行の要素数が同じでないと結合できないので、注意しましょう。

#aとbを縦方向に結合
np.vstack((a,b)) #引数はタプルにすること
>>実行結果
array([[ 1,  2,  3,  4],
[ 1,  2,  3,  4],
[ 5,  6,  7,  8],
[ 9, 10, 11, 12]])

ndarray配列を横方向に結合する時は、hstack関数を使います。


#array1とarray2の確認
array1
>>実行結果
array([1, 2, 3, 4, 5, 6])
array2
>>実行結果
array([ 2,  4,  6,  8, 10, 12])
#array1とarray2を横方向に結合
np.hstack((array1,array2))
>>実行結果
array([ 1,  2,  3,  4,  5,  6,  2,  4,  6,  8, 10, 12])



疑似乱数を生成する

疑似乱数を作る時はrandom関数を使います。


0~1の乱数

random.randで、0~1の乱数を生成できます。

引数には何を入れるのかな?


ベクトルの場合は、生成したい乱数の数(要素数)を入れます。

#ベクトル
np.random.rand(5)
>>実行結果
array([0.85572911, 0.41986047, 0.52022084, 0.60679373, 0.02879198])
where




行列の場合の引数は、(行,列)で指定します。

#行列
np.random.rand(4,6)
>>実行結果
array([[0.35599728, 0.14748427, 0.86172026, 0.92575276, 0.29228079,
0.22964651],
[0.34756348, 0.08573972, 0.59858781, 0.67060099, 0.00791902,
0.02872533],
[0.82821718, 0.75247201, 0.8961799 , 0.94816615, 0.48520699,
0.15950374],
[0.94662943, 0.81549464, 0.1551827 , 0.84437122, 0.20545317,
0.96384743]])



指定した範囲の整数の乱数

指定した範囲にある整数をランダムに選んで、ベクトルや行列を作りたい場合は、random.randintを使います。


#引数の数字以内で整数を1つ選ぶ
np.random.randint(30)
>>実行結果
13



#範囲指定(10~30)
np.random.randint(10,30)
>>27



#複数の乱数を生成する(ベクトル)
np.random.randint(10,30,6)
>>実行結果(要素数=6)
array([18, 17, 20, 21, 24, 25])



#複数の乱数を生成する(行列)
np.random.randint(10,30,(6,3))
>>実行結果
array([[21, 27, 22],
[16, 28, 11],
[10, 28, 28],
[19, 27, 10],
[27, 10, 28],
[28, 19, 12]])





最後に

Pythonでデータ分析・データサイエンスをしたい初心者向けに、Pythonデータ分析徹底解説総まとめページを作成しました。


流れに沿って実装することで、データ分析の基礎が固められます。

25
21
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
21