見出し画像

Numpy

NumPy(ナムパイ)は、Pythonで数値計算を効率的に行うための線形代数ライブラリです。特に、多次元配列を高速かつ効率的に扱うことに特化しており、機械学習やデータ分析の分野で広く利用されています


なぜNumPyを使うのか?

  • 高速な数値計算: C言語で実装されているため、Pythonの標準的なリストよりも高速な数値計算が可能です

  • 多次元配列: 行列やテンソルなどの多次元配列を簡単に扱うことができます

  • 豊富な数学関数: 三角関数、指数関数、統計関数など、様々な数学関数が用意されています

  • 便利な配列操作: スライシング、インデックス、ブロードキャスティングなど、配列を柔軟に操作するための機能が充実しています

  • 機械学習との親和性: scikit-learnなどの機械学習ライブラリと連携しやすく、データの前処理やモデルの構築に利用されます

基本的な使い方

import numpy as np

# 配列の作成
a = np.array([1, 2, 3])  # 1次元配列
b = np.array([[1, 2], [3, 4]])  # 2次元配列

# 形状の確認
print(a.shape)  # (3,)
print(b.shape)  # (2, 2)

# 要素へのアクセス
print(a[0])  # 1
print(b[1, 0])  # 3

# スライシング
print(a[1:3])  # [2 3]

# 演算
print(a + 1)  # [2 3 4]
print(a * b)  # ブロードキャスティングにより計算

NumPyの主な機能

  • ndarray : NumPyの中心となるデータ構造で、多次元配列を表します

  • ベクトル化 : 配列全体に対して一度に演算を行うことで、forループによる繰り返し処理を減らし、高速化を実現します

  • ブロードキャスティング : 形状の異なる配列同士の演算を自動的に行う機能です

  • ユニバーサル関数 : 全ての要素に同じ関数を適用する関数です

1.ndarrayの形状操作

reshape()

目的: 配列の形状を新しい形状に変える。

import numpy as np

a = np.arange(12)  # 0から11までの1次元配列
print(a)  # [0 1 2 3 4 5 6 7 8 9 10 11]

# 3行4列の2次元配列に変形
b = a.reshape(3, 4)
print(b)
# [[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]

resize()

  • 目的 : reshapeと同様、形状を変更する。

  • 違い : reshapeは新しい配列を返し、元の配列は変更されないが、resizeは元の配列自体を変更する。

a = np.arange(12)
a.resize(2, 6)
print(a)
# [[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]]

flatten()

  • 目的: 多次元配列を1次元配列に変形する。

  • ravel() も同様の機能を持つが、flattenは常に新しい配列を返す。

b = np.array([[1, 2], [3, 4]])
c = b.flatten()
print(c)  # [1 2 3 4]

次元の追加・削除

newaxis

  • 目的: 新しい次元を追加する。

a = np.array([1, 2, 3])
b = a[np.newaxis, :]  # (1, 3) の形状に変換
print(b.shape)

expand_dims()

  • 目的: newaxisと同様、新しい次元を追加する。

  • 引数: どの軸に次元を追加するかを指定できる。

a = np.array([1, 2, 3])
b = np.expand_dims(a, axis=0)  # (1, 3) の形状に変換
print(b.shape)

squeeze()

  • 目的: サイズが1の次元を削除する。

b = np.array([[1, 2, 3]])
c = b.squeeze()  # (3,) の形状に変換
print(c.shape)

2.ndarrayの演算

ndarrayの演算の特徴

  • 要素ごとの演算: 四則演算、比較演算、べき乗など、要素ごとに演算が行われます。

  • ブロードキャスティング: 形状が異なる配列同士でも、ある程度自動的に形状が調整され、演算が可能になります

  • ユニバーサル関数: 三角関数、指数関数、対数関数など、様々な数学関数がndarrayに対して適用できます。

import numpy as np

# 配列の作成
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])

# 要素ごとの加算
c = a + b  # [5 7 9]

# 要素ごとの乗算
d = a * b  # [4 10 18]

# スカラーとの演算
e = a * 2  # [2 4 6]

# 比較演算
f = a > 2  # [False False  True]

# ユニバーサル関数 (np.sin)
g = np.sin(a)
a = np.array([[1, 2, 3], [4, 5, 6]])
b = np.array([10, 20, 30])

c = a * b  # 各行にbの要素が対応して掛け算される

行列の積

行列の積は、@演算子またはnp.dot()関数を使用します

a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])

c = a @ b  # 行列の積
d = np.dot(a, b)  # 行列の積

3.統計量と集計関数

NumPyは、数値データの集計や統計処理を効率的に行うための豊富な関数を提供しています。これらの関数を使うことで、データの傾向を把握したり、特徴を抽出したりすることができます。

基本的な統計量

  • 平均値: np.mean()

  • 中央値: np.median()

  • 最頻値: scipy.stats.mode() (NumPy本体には含まれていないため、SciPyが必要)

  • 分散: np.var()

  • 標準偏差: np.std()

  • 最大値: np.max()

  • 最小値: np.min()

import numpy as np
from scipy import stats

# データの生成
data = np.array([3, 1, 4, 1, 5, 9, 2, 6, 5, 3])

# 平均値
mean = np.mean(data)
print("平均値:", mean)

# 中央値
median = np.median(data)
print("中央値:", median)

# 最頻値
mode = stats.mode(data)
print("最頻値:", mode.mode)

# 分散
var = np.var(data)
print("分散:", var)

# 標準偏差
std = np.std(data)
print("標準偏差:", std)

軸ごとの計算

多次元配列の場合、特定の軸に沿って統計量を計算することができます

data = np.array([[1, 2, 3], [4, 5, 6]])
row_mean = np.mean(data, axis=1)  # 各行の平均
col_mean = np.mean(data, axis=0)  # 各列の平均

4.ndarrayの比較と論理演算

NumPyのndarrayは、数値計算だけでなく、要素ごとの比較や論理演算も非常に強力に行うことができます。これにより、データのフィルタリングや条件に基づいた処理を効率的に行うことができます。

比較演算

ndarrayの要素同士またはndarrayとスカラー値を比較し、その結果をブール値のndarrayとして返します。

import numpy as np

a = np.array([1, 2, 3])
b = np.array([2, 2, 4])

# 要素ごとの比較
c = a == b  # [False  True False]
d = a > 2  # [False False  True]

論理演算

比較演算の結果得られたブール値のndarrayに対して、論理演算を行うことができます。

  • 論理演算子: & (AND), | (OR), ~ (NOT)

# 条件を組み合わせる
e = (a > 1) & (b < 4)  # [False  True False]

マスクの作成と利用

比較演算の結果得られたブール値のndarrayをマスクとして利用することで、特定の条件を満たす要素だけを取り出すことができます

# aの要素のうち、2以上の要素だけを取り出す
mask = a >= 2
result = a[mask]  # [2 3]

ユニバーサル関数による論理演算

NumPyには、np.all(), np.any(), np.where()などのユニバーサル関数が用意されており、論理演算の結果をまとめて評価することができます。

  • np.all(): 配列の全ての要素がTrueであるかどうか

  • np.any(): 配列のいずれかの要素がTrueであるかどうか

  • np.where(): 条件を満たす要素のインデックスを返す

# aの全ての要素が2以上かどうか
all_greater_than_2 = np.all(a > 2)  # False

# aのいずれかの要素が2以上かどうか
any_greater_than_2 = np.any(a > 2)  # True

# aの要素が2以上であれば1、そうでなければ0を返す
result = np.where(a >= 2, 1, 0)  # [0 1 1]


この記事が気に入ったらサポートをしてみませんか?