Numpy

【入門】numpyの使い方|15分で徹底攻略!

【入門】numpyの使い方|15分で徹底攻略!

 

 

  • numpyの機能が多すぎて混乱、重要なものを体系的に学びたい…
  • 重要なnumpyの文法を押さえたい

この悩みを解決します。

いまや『numpy』はPythonで数値計算・機械学習を行う際には必要不可欠なツールです。

確かに始めの頃は私も機能が多くて混乱していました。

本記事では、numpyの重要な文法・使えると便利な文法を整理し解説していきます。

記事を読み終えると、numpyをある程度自由自在に使えるようになります。

 

 

 

Numpyの基本知識

 

Numpyは、科学や数学のための数値計算ライブラリです。

Numpyを利用することで、データ解析で必要不可欠な行列の計算を高速で行うことができます。

下記をターミナルに入力することで『Numpy』をインストールすることができます。

 

$ pip3 install numpy

 

 

*Google Colabを使用している方は、デフォルでインストールされているので特にインストールする必要はありません。

Google Colabの導入方法に関しては下記を参考にしてください。

【10分で完了】Google Colabのインストール法・使い方Google Colabは、GPUを使用できるため、低コストかつ高速で機械学習の実装を行う際に必要不可欠なツールです。本記事では、Google Colabのインストール方法と注意事項を10〜15分程度でまとめました。...

 

Numpyのインポート

 

以下のコードをNotebook上で実行すると、Numpyをインポートできます。

import numpy as np

 

このようにインポートすることで、『np』でNumpyを呼び出すことができます。

この『np』という名付け方は慣習です。

 

Numpyの配列の生成方法

 

まずは、さまざまなNumpy配列を生成する方法を紹介していきます。

また、Numpyの配列のことは、一般的に『ndarray』と呼ばれます!

 

  1. array : ndarray配列を生成
  2. arange : 値が等間隔に変化する配列を生成
  3. linspace : 与えた範囲を等間隔に分割した配列を生成
  4. ones : 要素が1の配列を生成
  5. zeros : 要素が0の配列を生成
  6. eye : 単位行列を生成

詳しく説明していきます。

 

array : ndarray配列を生成

 

リストをarray関数に渡すことで、numpyが提供する『ndarray』配列を生成することができます。

まずは、一次元の配列を作ってみましょう。

np.array([1, 2, 3])

 

<output>

array([1, 2, 3])

 

次に二次元配列を作成してみましょう。

 

np.array([[1, 2, 3], [4, 5, 6]])

 

<output>

array([[1, 2, 3],
       [4, 5, 6]])

 

補足ですが、numpyでは、配列の次元をrankと言います。

つまり、ここまでrank=1, rank=2の配列を作ったことになります。

 

また、dtypeを指定することで、指定した型の配列を作ることができます。

# 型をfloatに設定
np.array([[1, 2, 3], [4, 5, 6]], dtype=float)

 

<output>

array([[1., 2., 3.],
       [4., 5., 6.]])

 

 

また、asarryを使ってもndarray配列を作ることができます。

np.asarray([1, 2, 3])

 

<output>

array([1, 2, 3])

 

arrayとasarrayの違いは値が同期されるかされないかの違いです。

少し応用なので、初心者の方は、np.arrayのみ利用できればOKです!!

 

一応、同期を理解するための具体例を紹介しておきます。

# コピーになる
lis1 = [1, 2, 3]
array1 = np.array(lis1)
array2 = np.array(array1)
array2[0] = 100
print(f'Case Array  {array1} : {array2}')

# 同期される
lis3 = [1, 2, 3]
array3 = np.asarray(lis3)
array4 = np.asarray(array3)
array4[0] = 100
print(f'Case Asarray  {array3}:{array4}')

 

<output>

Case Array  [1 2 3] : [100   2   3]
Case Asarray  [100   2   3]:[100   2   3]

 

 

 

arange : 値が等間隔に変化する配列を生成

 

arange関数は、引数として(start, stop, step)という形式で引数を与えることで配列を生成します。

*startの値は含みますが、stopの値は含まないことに注意しましょう。

 

np.arange(4, 20, 2)

 

<output>

array([ 4,  6,  8, 10, 12, 14, 16, 18])

 

 

 

Stepの部分に『-1』を指定することで、降順で配列を生成できます。

# 降順の配列を作成
np.arange(20, 10, -1)

 

<output>

array([20, 19, 18, 17, 16, 15, 14, 13, 12, 11])

 

 

linspace : 与えた範囲を等間隔に分割した配列を生成

 

linspace関数を用いることで、等間隔な配列を作ることができます。

引数としては、(start, stop, 要素数)を指定することができます。

*arangeのときと異なり、デフォルでstopの値を含みます!

 

np.linspace(0, 1, 5)

 

<output>

array([0.  , 0.25, 0.5 , 0.75, 1.  ])

 

 

 

引数にendpoint = Falseとすることでstopの値を含まなくすることができます。

np.linspace(0, 1, 5, endpoint = False)

 

<output>

array([0. , 0.2, 0.4, 0.6, 0.8])

 

 

ones : 要素が1の配列を生成

 

np.onesを用いることで、要素が1の配列を生成することができます。

引数には、タプル形式で配列の形状を入力します。

np.ones((2, 2))

 

<output>

array([[1., 1.],
       [1., 1.]])

 

 

zeros : 要素が0の配列を生成

 

np.zerosで要素が0の配列を生成することができます。

同様に、引数には、タプル形式で配列の形状を入力します。

np.zeros((3, 4))

 

<output>

array([[0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.]])

 

 

eye : 単位行列を生成

 

np.eyeを用いることで、単位行列を生成することができます。

引数には、生成する行列のサイズを指定してください。

 

np.eye(5)

 

<output>

array([[1., 0., 0., 0., 0.],
       [0., 1., 0., 0., 0.],
       [0., 0., 1., 0., 0.],
       [0., 0., 0., 1., 0.],
       [0., 0., 0., 0., 1.]])

 

 

 

Numpyによる乱数生成

 

次に、Numpyを用いて乱数を生成する方法を紹介します。

  1. random.seed : 乱数のシードを固定
  2. random.rand : 0〜1の一様乱数を生成
  3. random.randn : 標準正規分布から乱数生成
  4. random.randint : 指定した範囲の整数乱数を生成

 

random.seed : 乱数のシードを固定

 

乱数のシードを固定することで、乱数の再現性を担保することができます。

より簡単に説明すると、シードを固定することで毎回同じ乱数を生成するようになります!!

機械学習やデータ解析等では、再現性を担保することは大切なので最初に設定しておくことをオススメします。

具体的には、下記のコードで設定できます。

# 乱数のシードを固定
np.random.seed(1)

 

引数を他の数字にすることで、乱数のシードは変化します。

特に気にせず適当に数字を入力しましょう。

 

random.rand : 0〜1の一様乱数を生成

 

np.random.randを使用することで0〜1の一様乱数を生成することができます。

 

np.random.rand()

 

<output>

0.4728617697542056

 

下記のコードで多次元配列の一様乱数を生成することができます。

np.random.rand(5, 5)

 

<output>

array([[0.58949042, 0.2016367 , 0.6536451 , 0.96601509, 0.78657448],
       [0.20699415, 0.38918657, 0.64385908, 0.21698741, 0.28100744],
       [0.80928114, 0.15305058, 0.65002492, 0.86956368, 0.82423989],
       [0.54919992, 0.93332536, 0.59593206, 0.99904918, 0.99065101],
       [0.31950689, 0.67079156, 0.42423613, 0.64338711, 0.14761924]])

 

 

random.randn : 標準正規分布から乱数生成

 

np.random.randnを使用することで、平均0分散1の標準正規分布から乱数を生成することができます。

下記のコードで乱数を生成できます。

np.random.randn()

 

<output>

1.6243453636632417

 

多次元配列の乱数も下記のコードで生成できます。

np.random.randn(5, 5)

 

<output>

array([[-0.61175641, -0.52817175, -1.07296862,  0.86540763, -2.3015387 ],
       [ 1.74481176, -0.7612069 ,  0.3190391 , -0.24937038,  1.46210794],
       [-2.06014071, -0.3224172 , -0.38405435,  1.13376944, -1.09989127],
       [-0.17242821, -0.87785842,  0.04221375,  0.58281521, -1.10061918],
       [ 1.14472371,  0.90159072,  0.50249434,  0.90085595, -0.68372786]])

 

 

random.randint : 指定した範囲の整数乱数を生成

 

np.random.randintを利用することで指定した範囲の整数乱数を生成することができます。

具体例を以下に示します。

# 0以上10未満の整数をランダムに生成
np.random.randint(0, 10)

 

4

 

配列のサイズを指定する場合は、引数sizeを以下のように指定します。

np.random.randint(0, 10, size=(3, 3))

 

<output>

array([[4, 4, 3],
       [6, 8, 3],
       [0, 6, 0]])

 

 

numpy配列の演算

 

numpyの配列を生成する方法は理解できたと思うので、次は配列同士の演算を説明します。

 

一次元配列の演算

 

一次元配列の演算を以下にまとめます。

# サンプル
vec1 = np.array([1, 2, 3])
vec2 = np.array([4, 5, 6])

print("要素同士の足し算:", vec1+vec2)
print("要素同士の引き算:", vec1-vec2)
print("要素同士の掛け算:" ,vec1*vec2)
print("要素同士の割り算:", vec1/vec2)

print("数値との足し算:", vec1+2)
print("数値との引き算:", vec1-2)
print("数値との掛け算:", vec1*2)
print("数値との割り算:", vec1/2)

print("ベクトルの内積:", np.dot(vec1, vec2))

# @でも内積が計算できる
print("ベクトルの内積2:", vec1@vec2)

 

<output>

要素同士の足し算: [5 7 9]
要素同士の引き算: [-3 -3 -3]
要素同士の掛け算: [ 4 10 18]
要素同士の割り算: [0.25 0.4  0.5 ]
数値との足し算: [3 4 5]
数値との引き算: [-1  0  1]
数値との掛け算: [2 4 6]
数値との割り算: [0.5 1.  1.5]
ベクトルの内積: 32
ベクトルの内積2: 32

 

 

リストの場合は、足し算は『要素の結合』が実行されることに注意しましょう。

# リストの場合は配列の結合になる
lis1 = [1, 2, 3]
lis2 = [1, 2, 3]
lis1 + lis2 

<output>

[1, 2, 3, 1, 2, 3]

 

 

 

多次元配列の演算

 

次に多次元配列(代表例として二次元)の四則演算をまとめました。

array1 = np.array([[1, 2, 3], [4, 5, 6]])
array2 = np.array([[1, 2, 3], [4, 5, 6]])
array3 = np.array([[1, 2], [3, 4]])

print("要素同士の足し算:\n", array1+array2)
print("要素同士の引き算:\n", array1-array2)
print("要素同士の掛け算:\n", array1*array2)
print("要素同士の割り算:\n", array1/array2)

print("数値との足し算:\n", array1+2)
print("数値との引き算:\n", array1-2)
print("数値との掛け算:\n", array1*2)
print("数値との割り算:\n", array1/2)

print("行列積:\n", np.dot(array3, array3))
print("行列積(形状に注意):\n", np.dot(array3, array1))

print("行列積1:\n", array3@array3)
print("行列積2(形状に注意):\n", array3@array1)

 

<output>

要素同士の足し算:
 [[ 2  4  6]
 [ 8 10 12]]
要素同士の引き算:
 [[0 0 0]
 [0 0 0]]
要素同士の掛け算:
 [[ 1  4  9]
 [16 25 36]]
要素同士の割り算:
 [[1. 1. 1.]
 [1. 1. 1.]]
数値との足し算:
 [[3 4 5]
 [6 7 8]]
数値との引き算:
 [[-1  0  1]
 [ 2  3  4]]
数値との掛け算:
 [[ 2  4  6]
 [ 8 10 12]]
数値との割り算:
 [[0.5 1.  1.5]
 [2.  2.5 3. ]]
行列積:
 [[ 7 10]
 [15 22]]
行列積(形状に注意):
 [[ 9 12 15]
 [19 26 33]]
行列積:
 [[ 7 10]
 [15 22]]
行列積(形状に注意):
 [[ 9 12 15]
 [19 26 33]]

 

 

 

numpy配列のインデキシング・スライシング

 

ここでは、Numpyのインデキシングとスライシングについて解説していきます。

まずは、インデキシングについて解説していきます。

具体的に以下のサンプル配列を使って説明していきます。

# sample
array1 = np.array([[1, 2, 3], [4, 5, 6]])

 

 

numpyのインデキシング

 

インデキシングとは、配列のインデックスを指定して対応する要素を取り出す方法です。

 

まずは、1次元配列のインデキシングを紹介します。

1次元配列のインデキシング

 

以下に1次元配列のインデキシングをまとめました。

# 一次元配列のインデキシング
array1 = np.array([1, 2, 3])

# 一番目の配列を取り出す
print(array1[0])
# 最後の配列を取り出す
print(array1[-1])

 

 

多次元配列のインデキシング

 

多次元配列(具体例として2次元)のインデキシングを以下にまとめます。

# 二次元配列のインデキシング
array2 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

# 1行目を取り出す
print(array2[0])
# 最終行を取り出す
print(array2[-1])
# 1行2列目の要素を取り出す
print(array2[0, 1])

 

numpyのスライシング

 

『:』を使用して、取り出す要素を指定する方法をスライシングといいます。

具体的には、『a:b』と指定することで、『a以上b未満の配列』を取り出すことができます。

また、a, bを指定しない場合は、以下がデフォルトで設定されます。

  • aを指定しない場合は、先頭の配列がaに設定される
  • bを指定しない場合は、最後の配列がbに設定される

少し、難しいので具体例を見て習得しましょう!!

 

1次元配列のスライシング

 

まずは、1次元配列のスライシングを紹介します。

# 1次元配列のインデキシング
array3 = np.array([1, 2, 3, 4, 5])

# インデックスが1以上3未満の要素を取り出す
print(array3[1:3])
# インデックスが3未満の要素を取り出す
print(array3[:3])
# インデックスが1以上の要素を取り出す
print(array3[1:])

 

<output>

[2 3]
[1 2 3]
[2 3 4 5]

 

 

多次元配列のスライシング

 

次に多次元配列(具体例として2次元)のスライシングを紹介します。

# 二次元配列のインデキシング
array4 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

# 1行目, 2行目を取り出す
print(array4[:2, :])
# 1列目を取り出す
print(array4[:, 0])
# 2列目の1行目と2行目を取り出す
print(array4[:2, 1])

 

<output>

[[1 2 3]
 [4 5 6]]
[1 4 7]
[2 5]

 

*1列を取り出すと、1次元のndarray配列になることに注意しましょう。

2次元以上の多次元配列でもインデキシングとスライシングの方法は変わりません。

 

 

numpyでよく使うメソッド

 

ここからは、numpyでよく使用する基本的なメソッドを紹介していきます。

  1. shape : 形状を確認
  2. reshape : 形状を変換
  3. dtype : データの型を確認
  4. astype : データの型を変更

 

shape : 形状を確認

 

shapeで形状を確認することができます。

array1 = np.array([[1, 2, 3],
                   [4, 5, 6]])

# 配列の確認
array1.shape

 

<出力>

(2, 3)

 

こうすることで、2行3列の配列であることが確認できます。

reshape : 形状を変換

 

reshapeメソッドを用いて、形状を変換することができます。

具体的には、変更したい配列をReshapeの引数で指定してください

array1 = np.array([[1, 2, 3],
                   [4, 5, 6]])

# 配列の変更(変更したい配列をReshapeの後に指定)
print(array1.reshape(3, 2))

 

<出力>

array([[1, 2, 3],
       [4, 5, 6]])

 

以下のように、reshapeの引数に-1を入力することで、片方の配列をオートで決定してくれます。

array1 = np.array([[1, 2, 3],
                   [4, 5, 6]])

# 配列の変更(-1を使用する)
array1.reshape(1, -1)

 

<出力>

array([[1, 2, 3, 4, 5, 6]])

 

dtype : データの型を確認

 

dtypeを利用することで、データの型を確認することができます。

array1 = np.array([[1, 2, 3],
                   [4, 5, 6]])

# データの型を確認
array1.dtype

 

<出力>

dtype('int64')

 

 

astype : データの型を変更

 

astypeメソッドを利用することで、データの型を変更することができます。

以下の具体例では、『np.float64』から『np.int32』に変更しています。

<Input>

array1 = np.array([1.0, 1.1, 1.2])
print(f'変更前 : {array1}')

array2 = array1.astype(np.int32)
print(f'変更後 : {array2}')

 

<output>

変更前 : [1.  1.1 1.2]
変更後 : [1 1 1]

 

 

 

numpyでよく使う関数

 

numpyでよく使う基本的な関数を紹介していきます。

  1. where : 条件によって要素を変換
  2. unique : 重複する要素を削除する
  3. concatenate : 既存の次元方向に配列を結合
  4. stack : 新たな軸方向に配列を結合
  5. expand_dims : 次元を一つ増やす
  6. squeeze : shapeが1の次元を減らす

詳しく説明していきます。

 

where : 条件によって要素を変換

 

whereを利用することで、条件によって要素を変換することができます。

where関数の引数は、(条件, Trueのとき変換する値, Falseのとき変換する値)です。

array1 = np.array([[1, 2, 3],
                   [4, 5, 6]])

# 条件によって要素を変換
array2 = np.where(array1 > 3, 1, 0)
array2

 

<出力>

array([[0, 0, 0],
       [1, 1, 1]])

 

 

unique : 重複する要素を削除する

 

np.uniqueを利用することで、重複する要素を削除することができます。

具体例を以下に示します。

array1 = np.array([1, 1, 2, 3, 3])
np.unique(array1)

 

<output>

array([1, 2, 3])

 

 

 

concatenate : 既存の次元方向に配列を結合

 

np.concatenateを利用することで、既存の軸方向に、配列を結合することができます。

デフォルトでは、行方向の結合(axis=0)となっています。

具体例を以下に示します。

array1 = np.array([[1, 2, 3], [4, 5, 6]])
array2 = np.array([[7, 8, 9], [10, 11, 12]])

# 行方向に結合(default : axis=0)
print("行方向:\n", np.concatenate([array1, array2]))

# 列方向に結合
print("列方向:\n", np.concatenate([array1, array2], axis=1))

 

<output>

行方向:
 [[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]]
列方向:
 [[ 1  2  3  7  8  9]
 [ 4  5  6 10 11 12]]

 

配列のサイズが合わないと結合ができないことに注意しましょう。

 

stack : 新たな軸方向に配列を結合

 

np.stackを用いることで、新たな軸方向に結合することができます。

デフォルトでは、行方向の結合(axis=0)となっています。

具体例を以下に示します。

array1 = np.array([1, 2, 3])
array2 = np.array([4, 5, 6])

# 新たな次元で行方向に配列を結合(default : axis=0)
print("行方向:\n", np.stack([array1, array2]))

# 新たな次元で列方向に配列を結合
print("列方向:\n", np.stack([array1, array2], axis=1))

 

<output>

行方向:
 [[1 2 3]
 [4 5 6]]
列方向:
 [[1 4]
 [2 5]
 [3 6]]

 

np.concatenateの違いを見るための具体例を以下に表示します。

array1 = np.array([1, 2, 3])
array2 = np.array([4, 5, 6])

# concatenate
print("行方向(concatenate):\n", np.concatenate([array1, array2]))

# stack
print("行方向(stack):\n", np.stack([array1, array2]))
print("列方向(stack):\n", np.stack([array1, array2], axis=1))

 

<output>

行方向(concatenate):
 [1 2 3 4 5 6]
行方向(stack):
 [[1 2 3]
 [4 5 6]]
列方向(stack):
 [[1 4]
 [2 5]
 [3 6]]

 

 

 

expand_dims : 次元を一つ増やす

 

np.expand_dimsを利用することで、numpy配列の次元を一つ増やすことができます。

axisという引数を利用することで、追加する次元を指定することができます。

二次元配列の場合は、axis=0が行方向, axis=1が列方向に対応します。

具体例を以下に示します。

# 次元を一つ増やす
array1 = np.array([1, 2, 3])

# 次元を一つ増やす
new_array1 = np.expand_dims(array1, axis=0)
new_array2 = np.expand_dims(array1, axis=1)
# 最後の次元を増やす
new_array3 = np.expand_dims(array1, axis=-1)

print(array1.shape)
print(new_array1.shape)
print(new_array2.shape)
print(new_array3.shape)

 

<output>

(3,)
(1, 3)
(3, 1)
(3, 1)

 

 

 

squeeze : shapeが1の次元を減らす

 

np.squeezeを使用すると、shapeが1の次元を減らすことができます。

具体例を以下に示します。

 

array1 = np.array([[1, 2, 3]])

# shapeが1の部分の次元を減らす
array2 = np.squeeze(array1)

print(array1.shape)
print(array2.shape)

 

<output>

(1, 3)
(3,)

 

 

 

 

まとめ

 

numpyの基本的な使い方を紹介しました。

numpyを利用することで、機械学習や数式のプロットなどいろいろなことができるようになります。

さらに、numpyを利用することで、Pandas、Matplotlibというよう解析ツールも自由に使いこなすことが可能です。

 

ABOUT ME
努力のガリレオ
【運営者】 : 東大で理論物理を研究中(経歴)東京大学, TOEIC950点, NASA留学, カナダ滞在経験有り, 最優秀塾講師賞, オンライン英会話講師試験合格, ブログと独自コンテンツで収益6桁達成 【編集者】: イングリッシュアドバイザーとして勤務中(経歴)中学校教諭一種免許取得[英語],カナダ留学経験あり, TOEIC650点
Python学習を効率化させるサービス

 

Pythonを学習するのに効率的なサービスを紹介していきます。

まず最初におすすめするのは、Udemyです。

Udemyは、Pythonに特化した授業がたくさんあり、どの授業も良質です。

また、セール中は1500円定義で利用することができ、コスパも最強です。

下記の記事では、実際に私が15個以上の講義を受講して特におすすめだった講義を紹介しています。

 

【最新】UdemyでおすすめのPythonコース|東大生が厳選!10万を超える講座があるUdemyの中で、Pythonに関係する講座を厳選しました。また、本記事では、Udemyを使用しながらPythonをどのような順番で勉強するべきかを紹介しました。ぜひ参考にしてください。...

 

他のPythonに特化したオンライン・オフラインスクールも下記の記事でまとめています。

 

【最新】Pythonに強いプログラミングスクール7選|東大生が厳選Pythonの流行と共に、Pythonに強いプログラミングスクールが増えてきました。本記事では、特にPythonを効率的に学ぶことができるプログラミングスクールを経験をもとに厳選して、内容を詳しく解説しています。...

 

自分の学習スタイルに合わせて最適なものを選びましょう。