【初心者向け】Pythonのリストとnumpyの基本
Pythonでデータ分析や数値計算を行う際、リストとNumPy配列は欠かせない存在です。しかし、これらのデータ構造は、それぞれ異なる特性を持っています。リストは柔軟で様々な型の要素を格納できる一方、NumPy配列は数値計算に特化し、高速な処理を可能にします。
本記事では、リストとNumPy配列の違いと共通点の基本を解説します。さらに、NumPyの強力な機能であるブロードキャストについても解説し、NumPy配列をより効果的に活用する方法を紹介します。
和と積(と内積)
Pythonのリスト同士を足したり掛けたりする場合は、以下のような繰り返しのコードを書く必要があります。
a = [2, 9, 9, 7, 9, 2]
b = [3, 1, 4, 1, 5, 9]
# 和
add_ab = []
for i in range(len(a)):
add_ab.append(a[i] + b[i])
print('和:',add_ab)
# 積
vol_ab = []
for i in range(len(a)):
vol_ab.append(a[i] * b[i])
print('積:',vol_ab)
# 内積
inp = 0
for i in range(len(a)):
inp += a[i] * b[i]
print('内積:',inp)
和: [5, 10, 13, 8, 14, 11]
積: [6, 9, 36, 7, 45, 18]
内積: 121
それが、numpyを使うと、こんなに簡単にできてしまうんです。
import numpy as np
a = np.array(a)
b = np.array(b)
# 和
print('和:',a + b)
# 積
print('積:',a * b)
# 内積
print('内積:',np.dot(a, b))
和: [ 5 10 13 8 14 11]
積: [ 6 9 36 7 45 18]
内積: 121
とっても便利です。
numpyでつくる配列
numpyは2次元配列もつくれます。
c = np.array([[1, 2, 3],[4, 5, 6]])
c
array([[1, 2, 3],
[4, 5, 6]])
1次元配列を2次元配列にすることもできます。
d = a.reshape([2,3])
d
array([[2, 9, 9],
[7, 9, 2]])
2次元配列を1次元にすることもできます。
e = d.flatten()
e
array([1, 2, 3, 4, 5, 6])
f = d.ravel()
f
array([1, 2, 3, 4, 5, 6])
ravelとflattenの違いは、rabelが参照でflattenがコピーです。
ravelで得られた配列を変更すると、元の配列も変更されます。flattenで得られた配列を変更しても、元の配列は変更されません。
コードで確認してみます。
e[0] = 0 # flattenの結果に代入
d # 元の変数を確認
array([[1, 2, 3],
[4, 5, 6]])
f[0] = 0 # ravelの結果に代入
d # 元の変数を確認
array([[0, 2, 3],
[4, 5, 6]])
ravelで変換した結果に代入した時だけ、元の変数の値が変更されていました。
ブロードキャスト
NumPyのブロードキャストは、異なる形状を持つ配列間で算術演算を可能にする強力な機能です。通常、NumPy配列同士の演算は、形状が完全に一致している必要があります。しかし、ブロードキャストを利用することで、形状が異なる配列間でも特定の条件下で演算を行うことができます。
print(3*d)
[[ 0 6 9]
[12 15 18]]
すべての値にそれぞれ3がかけられました。
g = np.array([2, 3, 4])
print(g*d)
[[ 0 6 12]
[ 8 15 24]]
どの行にも[2, 3, 4]がかけられました。
ブロードキャストの仕組み
ブロードキャストは、以下のルールに従って配列の形状を調整し、演算を行います。
- 次元数の調整:
2つの配列の次元数が異なる場合、次元数が少ない方の配列の先頭に1の次元を追加し、次元数を合わせます。 - 形状の比較:
2つの配列の各次元のサイズを比較します。
サイズが等しいか、どちらかのサイズが1の場合、その次元は適合します。
サイズが1の次元は、演算時に他の配列の対応する次元のサイズに合わせて引き伸ばされます。 - 演算の実行:
適合する次元を持つ配列同士で、要素ごとの演算が行われます。
Discussion