Pythonライブラリ講座

NumPyとは? ndarrayとは?|配列の基本を徹底解説!

前のページ|次のページ

2章ではPythonのライブラリの1つである『NumPy』の概要について説明します。

また、『配列』(np.ndarray)の宣言・演算について解説します。

本連載講座【Python ライブラリ編】では、データサイエンスに必要なPythonライブラリやその使い方を基礎から学ぶことができます。

NumPyPandasMatplotlibScipySeabornについて、初学者の方にも分かりやすいよう丁寧に解説しています。

さらに、学習した内容を定着させられるように各章演習問題を用意しています。

・Pythonでデータ分析ができるようになりたい

・Pythonの基礎事項は一通り学んだので、さらに深く学びたい

このように考えている方はTech Teacherが運営する【Python ライブラリ編】で、Pythonによるデータサイエンスの学習をすることをお勧めします!

なお、『Pythonについて全く知らない』・『Pythonの基礎事項がまだ分かっていない』という方は、まずコチラの【Python 基礎編】で基礎を一通り学習してからライブラリ編に取り掛かりましょう!

<ライブラリ編 目次>

<ライブラリの基礎>
1章:ライブラリとは

<NumPy>
2章:NumPyの概要と配列(ndarray)
3章:統計量や次元の取得/ソート
4章:配列のインデックス
5章:numpy.whereによる条件制御
6章:配列の結合/分割
7章:乱数

<SciPy>
8章:SciPyの概要と基本操作

<Pandas>
9章:SeriesDataFrame/統計量の取得
10章:データの読み込み/書き込み
11章:データの取り出し/追加
12章:データのソート
13章:データの結合
14章:階層型インデックス
15章:groupbyによる集計
16章:マッピング処理
17章:欠損値の扱い

<Matplotlib>
18章:Matplotlibの概要
19章:pyplotインターフェース
20章:オブジェクト指向インターフェース

<Seaborn>
21章:Seabornの概要と基本操作

NumPyとは

NumPy ロゴ

NumPy』はPythonの数値計算ライブラリで、配列操作行列計算などに特化しています。

NumPyは科学計算を効率的に行うことができる非常に便利なライブラリで、世界中で広く用いられています。

ndarray』と呼ばれる配列型のデータ構造やrandomモジュールによる乱数生成などが特徴で、C言語で記述されたモジュールであるため高速な演算が可能です。

データサイエンスにおいて必要不可欠なライブラリですので、しっかり学習してマスターしましょう!

配列(np.ndarray)の宣言

NumPyはndarrayクラスによって定義される『配列』によるデータ操作に長けています。

この『配列』はPythonの『リスト』と似ていますが、別物なので注意しましょう。

Pythonのリストについては以下の記事で詳しく解説しています。

https://www.tech-teacher.jp/blog/pythonstandard9_listdict/

NumPyのインポート

まず初めに、NumPyをインポートする必要があります。

以下のコードを実行して、NumPyを使える状態にしましょう。

import numpy as np

なお、numpyをインポートするとき、「np」という名前を新たに付ける風習があるので、本講座でもそれに従って名前を付けることにします。

NumPyによる配列の宣言

NumPyを用いて配列を宣言するには以下のように「np.array()」として、括弧の中にリストを書きます。

# ndarrayの宣言
x = np.array([1, 2, 3, 4, 5])

x #確認
array([1, 2, 3, 4, 5])

NumPyでは計算速度を速くするために要素の『』を持っています。

以下に代表的な『型』の例を示しておきます。

説明
int32 符号付き整数(32bit)
float64 浮動小数点数(64bit)
complex128 複素数(64bit浮動小数点数の組)
bool_ 真理値

要素の型は「配列名.dtype」とすると確認できます。

x.dtype
dtype('int32')

さまざまな配列

多次元配列

np.arrayでは多次元配列を扱うことができます。

今回は例として2次元配列を宣言してみましょう。

# 2次元配列
y = np.array([[1,2,3], [4,5,6]])
print(y)
[[1 2 3]
 [4 5 6]]

np.arange()・np.linspace():等間隔の数値列を作成

np.arange()』を用いると、一定の刻み幅の配列を作ることができます。

引数を1つだけ与えた場合、0以上引数未満の整数列を返します。

x1 = np.arange(10)
print(x1)
[0 1 2 3 4 5 6 7 8 9]

また「np.arange(開始値, 終了値, 刻み幅)」とすると「開始値」以上「終了値」未満ので、指定した刻み幅の数列を返します。

# np.arange(開始値, 終了値, 刻み幅)
x2 = np.arange(1, 10, 2)
x3 = np.arange(3, 6, 0.4)

print(x2)
print(x3)
[1 3 5 7 9]
[3.  3.4 3.8 4.2 4.6 5.  5.4 5.8]

また、『np.linspace()』を用いると、指定した範囲を等分割した配列を作ることができます。

np.linspace(開始値, 終了値, 分割数)」とすると「開始値」以上「終了値」以下の範囲を指定した分割数で等分割した数列を返します。

# np.linspace(開始値, 終了値, 分割数)
y1 = np.linspace(0, 100, 5)
y2 = np.linspace(-1, 1, 4)

print(y1)
print(y2)
[  0.  25.  50.  75. 100.]
[-1.         -0.33333333  0.33333333  1.        ]

arange()刻み幅を自分で指定したいとき、linspace()は配列の要素数(分割数)を指定したいときに便利です。

状況に応じて適切に使い分けることを意識しましょう!

np.zeros()・np.ones()すべての要素が0/1の配列

np.zeros()』を用いると、指定したサイズですべての要素が0である配列を作ることができます。

引数として複数の値を並べたタプルを渡すと、多次元配列が作成されます。

『タプル』とは、要素を並べて1つの組として表したものです。一見リストに似ていますが、要素の変更ができないなどの違いがあります。

例えば、「np.zeros((2, 3))」とした場合、2行×3列の配列が作成されます。

2次元以上の配列を作成する場合は引数をタプルにすることを忘れないようにしましょう。

x1 = np.zeros(5) # 1次元配列
x2 = np.zeros((2, 3)) #2次元配列

print(x1)
print(x2)
[0. 0. 0. 0. 0.]
[[0. 0. 0.]
 [0. 0. 0.]]

もちろん3次元以上の配列も作ることができます。ぜひ試してみてください。

また、『np.ones()』を用いると、指定したサイズですべての要素が1である配列を作ることができます。

y1 = np.ones(3) # 1次元配列
y2 = np.ones((3, 1)) #2次元配列

print(y1)
print(y2)
[1. 1. 1.]
[[1.]
 [1.]
 [1.]]

ndarray.reshape():配列の再形成

NumPyの配列の形状を変えるには『reshapeメソッド』を使います。

numpyのreshape関数を用いる方法もありますが、今回はreshapeメソッドを取り上げて解説します。

ndarray.reshape(形状を表すタプル・リスト)」の形で使用することができます。

以下の例では0から5の整数値を要素として持つ1次元配列を2×3の2次元配列に再形成しています。

x = np.arange(6).reshape((2, 3))

print(x)
[[0 1 2]
 [3 4 5]]

reshape()の括弧内にタプルを書くため、括弧が二重になっていることに注意しましょう。

こちらのメソッドは単純な操作ですが非常によく用いられるので、しっかり覚えておきましょう。

配列の演算

NumPyでは算術演算子などを用いて、配列同士または配列とスカラー間で演算をすることができます。

なお、算術演算子については以下の記事で詳しく解説していますので、忘れてしまった方や不安な方はぜひ参照してください。

https://www.tech-teacher.jp/blog/pythonstandard4_numbers/

要素ごとの演算

通常のPythonで用いられる算術演算子を配列に対して用いると、要素ごとに計算がなされます。

#要素ごとの計算
x = np.array([3, 5, 7, 9])
y = np.array([1, 2, 3, 4])

print(x + y)
print(x - y)
print(x * y)
print(x / y)
print(x // y)
print(x % y)
print(x ** y)
[ 4  7 10 13]
[2 3 4 5]
[ 3 10 21 36]
[3.         2.5        2.33333333 2.25      ]
[3 2 2 2]
[0 1 1 1]
[   3   25  343 6561]

また、『ブロードキャスト』という機能を用いて配列のすべての要素に対する計算を行うこともできます。

ブロードキャスト』とは、四則演算などにおいて配列の形状を自動で揃えて計算を行うというNumPyの重要な機能のひとつです。

以下の例で動作を確認してみましょう。

# 配列とスカラー間の計算
x = np.array([1, 2, 3, 4, 5])

print(x + 1)
print(5 % x)
[2 3 4 5 6]
[0 1 2 1 0]

配列x=[1,2,3,4,5]に対して「x+1」を計算する場合、右側の1が自動的に[1,1,1,1,1]という配列に変換されてから要素ごとの計算が行われます。

『ブロードキャスト』機能により、演算を簡潔に記述することができます。積極的に使っていきましょう。

行列としての演算

NumPyでは行列に対する演算子や関数・メソッドをもちいて、行列積転置行列を簡単に求めることができます。

主な演算子・関数・メソッドは以下の通りです。

演算子・関数・メソッド 説明
@ もしくは np.dot() 行列積(要素ごとの積ではないことに注意)
.T 行列の転置

では、実際に使用して確かめてみましょう。

# 行列積
mat1 = np.array([[0,1], [2,3]])
mat2 = np.array([[1,2], [3,4]])

print(mat1 @ mat2)
print(np.dot(mat1, mat2))
[[ 3  4]
 [11 16]]
[[ 3  4]
 [11 16]]
# 行列の転置
mat3 = np.array([[1,2], [3,4]])

print(mat3) # 元の行列
print(mat3.T) # 転置した行列
[[1 2]
 [3 4]]
[[1 3]
 [2 4]]

行列積は左側の行列の列数右側の行列の行数が等しくないと計算できないので、使用する場合は行列のサイズに注意しましょう。

2章の練習問題

以下の練習問題を解いてみましょう。

練習問題

問1. 以下の条件を満たす配列(ndarray)を宣言し、それぞれ出力してください。

(1) 先頭から順に「1,1,2,3,5」を要素として持つ長さ5の配列
(2) 1から始まり、刻み幅を7として100未満の整数を並べた配列(例:[1, 8, 15, 22…])
(3) 0以上10以下の範囲を要素数が30になるように等分割した配列
(4) すべての要素が0で、サイズが1行×10列の配列(例:[0, 0, 0…])
(5) すべての要素が1で、サイズが3行×4列の配列

問2. 以下の配列x, yに対して、(1)~(6)をそれぞれ求めてください。

x = [[2,4], [6,8]]
y = [[1,2], [3,2]]

(1) xとyの要素ごとの和
(2) xとyの要素ごとの商
(3) xのすべての要素に10を足した配列
(4) yのすべての要素を5で割った配列
(5) xとyの行列積
(6) yの転置行列

解答

問1(クリックして解答を表示)
#(1)
arr1 = np.array([1,1,2,3,5])
#(2)
arr2 = np.arange(1, 100, 7)
#(3)
arr3 = np.linspace(0, 10, 30)
#(4)
arr4 = np.zeros(10) 
#(5)
arr5 = np.ones((3, 4))

print(arr1)
print(arr2)
print(arr3)
print(arr4)
print(arr5)
[1 1 2 3 5]
[ 1  8 15 22 29 36 43 50 57 64 71 78 85 92 99]
[ 0.          0.34482759  0.68965517  1.03448276  1.37931034  1.72413793
  2.06896552  2.4137931   2.75862069  3.10344828  3.44827586  3.79310345
  4.13793103  4.48275862  4.82758621  5.17241379  5.51724138  5.86206897
  6.20689655  6.55172414  6.89655172  7.24137931  7.5862069   7.93103448
  8.27586207  8.62068966  8.96551724  9.31034483  9.65517241 10.        ]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[[1. 1. 1. 1.]
 [1. 1. 1. 1.]
 [1. 1. 1. 1.]]

問2(クリックして解答を表示)
x = np.array([[2, 4], [6, 8]])
y = np.array([[1, 2], [3, 2]])

#(1)
print("x+y:")
print(x + y)
#(2)
print("x/y")
print(x / y)
#(3)
print("x+10:")
print(x + 10)
#(4)
print("5/y:")
print(5 / y)
#(5)
print("dot(x, y):")
print(np.dot(x, y))
#(6)
print("y^T:")
print(y.T)
x+y:
[[ 3  6]
 [ 9 10]]
x/y
[[2. 2.]
 [2. 4.]]
x+10:
[[12 14]
 [16 18]]
y/5:
[[0.2 0.4]
 [0.6 0.4]]
dot(x, y):
[[14 12]
 [30 28]]
y^T:
[[1 3]
 [2 2]]

次のページへ

https://www.tech-teacher.jp/blog/?p=11220