Pythonでデータ分析や機械学習を始めようとすると、必ずと言っていいほど登場するのが「NumPy(ナムパイ)」というライブラリです。
NumPyは、数値計算を効率的かつ高速に行うための様々な機能を提供しており、現代のデータサイエンスにおける土台とも言える存在です。
「Pythonのリストと何が違うの?」
「どうやって使えばいいのかわからない・・・」
この記事では、上記のような疑問を抱える初心者の方に向けて、NumPyの基本的な使い方から、データ分析でよく使う便利な機能まで、豊富なサンプルコードを交えながら徹底的に解説していきます。
【本記事の信頼性】
- 執筆者は元エンジニア
- 大手プログラミングスクールのWebディレクター兼ライターを経験
- 自らも地元密着型のプログラミングスクールを運営
受講生から評判の良いプログラミングスクール
スクール |
特徴 |
受講料金 |
大手比較サイトで4年連続人気NO.1!受講生からの評判も非常に高く、Web系のエンジニアを目指すならRUNTEQ一択。 | 657,000円 (最大約53万円の給付金が適用される) |
|
月単価80万円以上の現役エンジニア講師による指導!一度入会すればサポートは半永久的。 | 498,000円 |
|
格安で質の高いWeb制作スキルを習得したい人におすすめ!業界最安級の料金でありながら、コミュニティやサポートが充実。 | 129,800円~ |
|
完全無料でプログラミングが学べる貴重なスクール!最短1ヶ月で卒業可能。ゼロスク運営会社への就職もできる。 | 完全無料 |
|
長期間に渡って学習し、希少人材を目指す人に最適なスクール!受講料は高いものの、高収入を得られる人材を目指せる。 | 96~132万円 |
NumPyとは? なぜ必要なのか
NumPy(Numerical Python)は、Pythonで数値計算、特に多次元配列を扱うためのライブラリです。
その最大の特徴は、ndarray
(N-dimensional array)という高性能な配列オブジェクトにあります。
Pythonには標準で「リスト」がありますが、NumPyの配列はリストに比べて以下のような大きなメリットを持っています。
高速な処理性能 | NumPyの内部はC言語で実装されており、Pythonのループ処理よりも遥かに高速に計算を実行できます。 |
メモリ効率 | 同じ要素数の場合、Pythonのリストよりも少ないメモリ使用量で済みます。 |
豊富な数学関数 | 配列全体の各要素に対して一括で計算を行う機能(ユニバーサル関数)や、統計処理、線形代数のための関数が数多く用意されています。 |
大量のデータを扱うデータ分析や機械学習の分野では、この処理速度と機能の豊富さが不可欠であり、だからこそNumPyが標準的に使われているわけです。
NumPyを使うための環境構築
まずはNumPyを使えるように、自身のPC環境にインストールするところから始めましょう。
NumPyのインストール
NumPyは、Pythonのパッケージ管理ツールであるpip
を使って簡単にインストールできます。
ターミナル(Windowsの場合はコマンドプロンプト)を開き、以下のコマンドを実行してください。
pip install numpy
これでインストールは完了です。
NumPyのインポート
インストールしたNumPyをPythonプログラムで使うためには、「インポート」という作業が必要です。
慣例として、np
という別名を付けてインポートするのが一般的となっています。
import numpy as np
これ以降、np
という名前でNumPyの機能にアクセスできるようになります。
NumPy配列 (ndarray) の作り方
NumPyの基本は、ndarray
と呼ばれる多次元配列です。
ここでは、様々なndarray
の作成方法を見ていきましょう。
Pythonのリストから作成 (np.array)
最も基本的なのが、Pythonのリストやタプルから配列を作成する方法です。
import numpy as np
# 1次元配列
list_1d = [1, 2, 3, 4, 5]
arr_1d = np.array(list_1d)
print(arr_1d)
print(type(arr_1d))
# 2次元配列
list_2d = [[1, 2, 3], [4, 5, 6]]
arr_2d = np.array(list_2d)
print(arr_2d)
実行結果は以下の通りです。
[1 2 3 4 5]
<class 'numpy.ndarray'>
[[1 2 3]
[4 5 6]]
np.array()
にリストを渡すことで、NumPy配列に変換されているのがわかります。
連続した値の配列を作成 (np.arange)
Pythonのrange
関数のように、連続した整数の配列を簡単に作成できます。
import numpy as np
# 0から9までの配列
arr1 = np.arange(10)
print(arr1)
# 1から10まで、2刻みの配列
arr2 = np.arange(1, 11, 2)
print(arr2)
実行結果は以下の通りです。
[0 1 2 3 4 5 6 7 8 9]
[1 3 5 7 9]
特定の値で埋められた配列を作成
np.zeros()
やnp.ones()
を使うと、全ての要素が0や1で埋められた配列を作成できます。
これは、後から値を入れるための配列を初期化する際によく使われます。
import numpy as np
# すべて0の3x4配列(3行4列)
zeros_arr = np.zeros((3, 4))
print(zeros_arr)
# すべて1の2x5配列
ones_arr = np.ones((2, 5))
print(ones_arr)
実行結果:
[[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
[[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]]
乱数で配列を作成 (np.random)
機械学習の重みの初期化やシミュレーションなど、乱数で配列を生成したい場面も多いでしょう。
np.random
モジュールがその役割を担います。
import numpy as np
# 0.0以上1.0未満の一様乱数で2x3配列を生成
rand_arr = np.random.rand(2, 3)
print(rand_arr)
# 平均0, 標準偏差1の正規分布(ガウス分布)に従う乱数で3x3配列を生成
randn_arr = np.random.randn(3, 3)
print(randn_arr)
# 1から10までの整数乱数を5個生成
randint_arr = np.random.randint(1, 11, 5)
print(randint_arr)
実行結果の例としては以下の通りです。(乱数のため結果は毎回異なります)
[[0.123 0.456 0.789]
[0.987 0.654 0.321]]
[[-1.234 0.567 2.345]
[ 0.111 -0.222 1.444]
[-0.999 0.888 -1.777]]
[5 9 1 3 8]
配列の基本操作
作成した配列の情報を確認したり、特定の要素にアクセスしたりする方法を学びましょう。
配列の形状と次元数 (shape, ndim, size)
配列がどのような形をしているかを知ることは非常に重要です。
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(f"形状 (shape): {arr.shape}")
print(f"次元数 (ndim): {arr.ndim}")
print(f"要素数 (size): {arr.size}")
実行結果は以下の通りです。
形状 (shape): (2, 3)
次元数 (ndim): 2
要素数 (size): 6
shape
: 配列の形状を(行数, 列数)
のタプルで返します。ndim
: 配列の次元数を返します。size
: 配列に含まれる全要素数を返します。
インデックス参照 (Indexing)
配列の特定の要素にアクセスするには、Pythonのリストと同様にインデックスを指定します。
import numpy as np
# 1次元配列
arr1 = np.arange(10, 60, 10)
print(arr1)
print(arr1[0]) # 最初の要素
print(arr1[2]) # 3番目の要素
# 2次元配列
arr2 = np.array([[1, 2, 3], [4, 5, 6]])
print(arr2)
print(arr2[0, 1]) # 1行目、2列目の要素 (0-indexed)
実行結果は以下の通りです。
[10 20 30 40 50]
10
30
[[1 2 3]
[4 5 6]]
2
スライシング(Slicing)
配列の一部を範囲指定で取り出す「スライシング」も、リストと同じように:
を使って行えます。
import numpy as np
# 1次元配列
arr1 = np.arange(10)
print(arr1[2:5]) # インデックス2から5の手前まで
# 2次元配列
arr2 = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
print(arr2[0:2, 1:3]) # 1〜2行目、2〜3列目の部分配列
実行結果は以下の通りです。
[2 3 4]
[[2 3]
[6 7]]
スライシングは、データの前処理などで特定の範囲のデータを抽出する際に頻繁に利用されます。
NumPyの核心機能!高速化の秘密
NumPyがなぜ高速なのか。
その秘密は「ユニバーサル関数」と「ブロードキャスティング」という2つの重要な機能にあります。
ユニバーサル関数(UFunc)
ユニバーサル関数とは、配列の各要素に対して一括で数学的な処理を行う関数です。
これにより、Pythonのfor
ループを書くことなく、簡潔かつ高速に計算できます。
import numpy as np
arr = np.array([1, 2, 3, 4])
# 各要素を2倍する
result1 = arr * 2
print(result1)
# 各要素の平方根を求める
result2 = np.sqrt(arr)
print(result2)
実行結果は以下の通りです。
[2 4 6 8]
[1. 1.414 1.732 2. ]
for
ループで書くよりも遥かにシンプルで、内部的に最適化された計算が実行されるため非常に高速です。
ブロードキャスティング
ブロードキャスティングは、shape
が異なる配列同士の計算を適切に行ってくれる機能です。
不足している次元や要素を、あたかも配列が拡張(ブロードキャスト)されたかのように振る舞い、計算を可能にします。
import numpy as np
arr1 = np.array([[1, 2, 3], [4, 5, 6]]) # (2, 3)の配列
arr2 = np.array([10, 20, 30]) # (3,)の1次元配列
# arr2がブロードキャストされて、arr1の各行に足し算される
result = arr1 + arr2
print(result)
実行結果は以下の通りです。
[[11 22 33]
[14 25 36]]
この例では、(2, 3)
のarr1
と(3,)
のarr2
を足し算しています。
NumPyはarr2
を[[10, 20, 30], [10, 20, 30]]
という(2, 3)
の配列であるかのように拡張し、要素ごとの足し算を実行してくれます。
この機能のおかげで、柔軟な計算が可能になるのです。
よく使う便利な関数
最後に、データ分析や機械学習の前処理で頻繁に使われる、便利な関数をいくつか紹介します。
基本的な統計量の計算
配列全体の合計値や平均値、最大値などを簡単に求めることができます。
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(f"合計: {np.sum(arr)}")
print(f"平均: {np.mean(arr)}")
print(f"最大値: {np.max(arr)}")
print(f"最小値: {np.min(arr)}")
# 列ごとの合計
print(f"列ごとの合計: {np.sum(arr, axis=0)}")
# 行ごとの合計
print(f"行ごとの合計: {np.sum(arr, axis=1)}")
実行結果は以下の通りです。
合計: 21
平均: 3.5
最大値: 6
最小値: 1
列ごとの合計: [5 7 9]
行ごとの合計: [ 6 15]
axis
引数を指定することで、計算を行う軸(0
なら列方向、1
なら行方向)を指定できます。
配列の形状を変更 (reshape)
配列の要素数を変えずに、形状だけを変更したい場合にreshape
を使います。
import numpy as np
arr = np.arange(12)
print(arr)
# 1次元配列を3x4の2次元配列に変換
reshaped_arr = arr.reshape(3, 4)
print(reshaped_arr)
実行結果は以下の通りです。
[ 0 1 2 3 4 5 6 7 8 9 10 11]
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
まとめ
今回は、Pythonの数値計算ライブラリNumPyの基本的な使い方について解説しました。
なお、Pythonを体系的に学んだり、Pythonのスキルを高めたりするためには、プログラミングスクールを利用するのも有効です。
細かな疑問がすぐに解決するだけでなく、現役エンジニアが「質の高いポートフォリオ」を作成するための手助けをしてくれたり、エンジニア就職・転職のコツを教えてくれたりするなど、様々なメリットがありますので、独学に疲れた方は検討してみてはいかがでしょうか。