配列の作成、属性の確認、形状変換、計算、集計について、順を追って学べるように整理しています。
参考として、次の記事も参照してください。
Pandasライブラリ紹介
Matplotlibライブラリ紹介
データサイエンティストのためのPythonライブラリ応用(上級編)
導読
- この文書は、なぜ NumPy を使うのか -> 配列を作る -> 配列の性質をつかむ -> 計算する -> よく使う関数で集約する、という流れで NumPy の全体像を最初に押さえるためのメモです。
- 読み始めるときは、まず
np.array()、shape、ndim、reshape()、np.newaxis、ブロードキャスト、ブールマスク、sum()/mean()を優先して押さえると、その後の Pandas や機械学習のコードも読みやすくなります。
この文書の章立ては、次のようになっています。
- なぜ NumPy を使うのか
- Python の for ループが遅くなりやすい理由:
%timeitで通常の Python ループと NumPy のベクトル化を比較します。 - NumPy が高速な理由: C 実装、同一
dtype、連続メモリ配置、並列化しやすい処理系という観点で整理します。 - どんな場面で役立つか: ベクトル演算、行列演算、行単位の一括処理に向くことを確認します。
- Python の for ループが遅くなりやすい理由:
- NumPy 配列の作成
- リストから作る:
np.array()、dtype指定、二次元配列。 - 固定値の配列を作る:
zeros()、ones()、full()、eye()。 - 数列を作る:
arange()、linspace()、logspace()。 - 乱数や抽出:
random()、normal()、randint()、permutation()、shuffle()、choice()。
- リストから作る:
- NumPy 配列の性質
- 配列の属性:
shape、ndim、size、dtype。 - インデックス: 一次元配列と二次元配列の要素アクセス。
- スライス: 行・列の取り出し、ビューとコピーの違い。
- 変形:
reshape()、np.newaxis、flatten()、ravel()。 - 結合と分割:
hstack()、c_、vstack()、r_、split()、hsplit()、vsplit()。
- 配列の属性:
- NumPy の基本演算
- ベクトル化演算: スカラーとの四則演算、絶対値、三角関数、指数、対数、配列同士の演算。
- 行列演算: 転置、
dot()、np.dot()、@が担う意味。 - 線形代数の基本:
linalg.det()、linalg.inv()、linalg.solve()、linalg.eig()、matrix_rank()、trace()。 - ブロードキャスト: 形状の異なる配列を規則に沿って一括計算します。
- 比較演算とマスク: 条件式、
all()、any()、ブールマスクによる抽出。 - ファンシーインデックス: インデックス配列で欲しい位置だけをまとめて抜き出します。
- その他のよく使う NumPy 関数
- 並べ替え:
sort()、argsort()。 - 最大値と最小値:
max()、min()、argmax()、argmin()。 - 合計と積:
sum()、prod()。 - 代表値:
median()、mean()、var()、std()。
- 並べ替え:
なぜ NumPy を使うのか
この章では、NumPy を使う意味を先に整理します。単に「速いライブラリ」と覚えるのではなく、どこが遅くなりやすく、なぜ改善されるのかを理解しておくと、その後の配列操作がつながって見えやすくなります。
Python の for ループが遅くなりやすい理由
通常の Python リストに対して 1 要素ずつ処理をかけると、ループのたびに型判定や関数探索が入るため、大きなデータでは速度差が目立ちます。Notebook では、100 万個の逆数計算を例に、素朴なループと NumPy の一括計算を比較しています。
def compute_reciprocals(values):
result = []
# Python の for ループで 1 要素ずつ逆数を計算する
for value in values: # 各要素ごとに解釈と処理が走る
result.append(1 / value)
return result
# まずは Python のリストで速度を測る
values = list(range(1, 1_000_000))
%timeit compute_reciprocals(values)
import numpy as np
# 次に NumPy 配列へ置き換えて同じ処理を測る
values = np.arange(1, 1_000_000)
%timeit 1 / values
Notebook 上では %timeit を使うと、同じ処理を複数回実行して平均時間を確認できます。NumPy の配列演算は、同じ逆数計算でも Python の手書きループより大幅に速くなります。
NumPy が高速な理由
NumPy が速い背景は、主に次の 3 点です。
- C 言語ベースで実装されており、処理系が配列演算をまとめて実行しやすいこと。
- 配列内の要素型がそろっており、データが連続したメモリ領域に置かれること。
- 一括演算を前提にしているため、低レベル側で最適化や並列化が効きやすいこと。
NumPy 配列が、数値計算向けに設計された配列であることを、最初に意識しておくのが重要です。
どんな場面で NumPy が役立つか
ループでベクトルや行列を 1 要素ずつ処理したくなったら、まず NumPy に置き換えられないかを考えるのが基本です。特に、ベクトルの要素ごとの計算、内積、行列積、行単位や列単位の一括変換では NumPy が自然です。
import numpy as np
# 要素ごとの計算
x = np.array([1, 2, 3])
y = np.array([4, 5, 6])
print(x + y)
print(x * y)
# ベクトルの内積
print(np.dot(x, y))
# 2 次元配列では行列積もそのまま書ける
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
print(a @ b)
NumPy 配列の作成
この章では、NumPy 配列をどのように用意するかを整理します。最初は np.array() だけでも十分ですが、固定値配列、等間隔配列、乱数配列をすぐ作れるようになると、検証用コードを短く書けるようになります。
リストから NumPy 配列を作る
最も基本的な入り口は np.array() です。一次元のリストから配列を作るだけでなく、dtype を明示して型をそろえたり、入れ子リストから二次元配列を作ったりできます。
import numpy as np
# まずは一次元配列を作る
x = np.array([1, 2, 3, 4, 5])
print(x)
print(type(x))
print(x.shape)
# dtype を指定して型を固定する
x = np.array([1, 2, 3, 4, 5], dtype="float32")
print(x)
print(type(x[0]))
# 入れ子リストを渡すと二次元配列になる
x = np.array([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
])
print(x)
print(x.shape)
固定値の配列を作る
NumPy には、最初から形を指定して固定値の配列を作る関数がそろっています。zeros()、ones()、full()、eye() は、初期値や形をそろえた配列をすばやく用意したいときに便利です。
import numpy as np
# 0 で埋めた配列
print(np.zeros(5, dtype=int))
# 1 で埋めた配列
print(np.ones((2, 4), dtype=float))
# 任意の値で埋めた配列
print(np.full((3, 5), 8.8))
# 単位行列
print(np.eye(3))
数列を作る
arange()、linspace()、logspace() は、規則性のある数値を並べた配列を作るときに使います。等差数列や等比数列をすばやく用意できるので、検証用データや軸の値を作る場面でよく使います。
import numpy as np
# 等差数列を作る
print(np.arange(1, 15, 2))
# 指定した個数で等間隔に区切る
print(np.linspace(0, 1, 4))
# 対数スケールの数列を作る
print(np.logspace(0, 9, 10))
乱数配列を作る
ランダムな配列を用意できると、計算や集計の練習がしやすくなります。Notebook では、一様乱数、正規乱数、整数乱数をそれぞれ作っています。
import numpy as np
# 0 以上 1 未満の一様乱数
print(np.random.random((3, 3)))
# 平均 0、標準偏差 1 の正規乱数
print(np.random.normal(0, 1, (3, 3)))
# 整数乱数
print(np.random.randint(0, 10, (3, 3)))
ランダムな並び替えとサンプリング
permutation() は元配列を残したまま並び替えた結果を返し、shuffle() は元配列自体を書き換えます。choice() はランダム抽出に使い、p= を与えると重み付き抽出にもできます。
import numpy as np
x = np.array([10, 20, 30, 40])
# 元の配列はそのままで、並び替えた結果だけを返す
print(np.random.permutation(x))
# shuffle() は元の配列自体を書き換える
print(x)
np.random.shuffle(x)
print(x)
base = np.arange(10, 25, dtype=float)
# 指定した配列からランダムに抽出する
print(np.random.choice(base, size=(4, 3)))
# 0 から 9 までを抽出候補にする書き方
print(np.random.choice(10, 10))
# 重み付きサンプリング
weights = base / np.sum(base)
print(np.random.choice(base, size=(4, 3), p=weights))
NumPy 配列の性質
この章では、配列の中身をどう見るか、どう切り出すか、どう変形するかをまとめます。ここを押さえると、後半の計算やブロードキャストの意味がかなり明確になります。
配列の属性を確認する
配列を見たら、まず shape、ndim、size、dtype を確認する習慣をつけると安全です。形状、次元数、要素数、型が分かれば、その配列を次の処理へ渡せるかをかなり早く判断できます。
import numpy as np
# 3 x 4 の乱数配列を作って属性を順に確認する
x = np.random.randint(10, size=(3, 4))
print(x)
print(x.shape)
print(x.ndim)
print(x.size)
print(x.dtype)
# 一次元配列では次元数が 1 になる
y = np.arange(10)
print(y)
print(y.ndim)
一次元配列と多次元配列のインデックス
一次元配列ではリストと同様に位置指定できます。二次元以上では、x[row, col] と x[row][col] の両方が使えますが、NumPy では前者の表現に慣れておく方が自然です。
また、NumPy 配列は dtype が固定なので、整数配列へ浮動小数点数を代入すると型に合わせて値が変換されます。
import numpy as np
# 一次元配列では通常の添字アクセスを使う
x1 = np.arange(10)
print(x1)
print(x1[0])
print(x1[5])
print(x1[-1])
# 二次元配列では 行, 列 の順で指定する
x2 = np.random.randint(0, 20, (2, 3))
print(x2)
print(x2[0, 0])
print(x2[0][0])
# 整数配列へ小数を代入すると整数へ変換される
x2[0, 0] = 1.618
print(x2)
配列のスライス
スライスは一次元でも多次元でも頻出です。行や列の一部を抜き出すときだけでなく、逆順化、間引き、特定の行列ブロックの取り出しにも使います。
import numpy as np
x1 = np.arange(10)
print(x1)
# 先頭から 3 要素を取り出す
print(x1[:3])
# 4 番目以降を取り出す
print(x1[3:])
# 逆順に並べ替える
print(x1[::-1])
x2 = np.random.randint(20, size=(3, 4))
print(x2)
# 左上の 2 行 3 列を切り出す
print(x2[:2, :3])
# 列を 1 列おきに抜き出す
print(x2[:2, 0:3:2])
# 行も列も逆順にする
print(x2[::-1, ::-1])
x3 = np.random.randint(20, size=(3, 4))
print(x3)
# 1 行だけ取り出す
print(x3[1, :])
print(x3[1])
# 3 列目だけ取り出す
print(x3[:, 2])
スライスはビューかコピーか
NumPy のスライスは、基本的に元配列のビューです。つまり、切り出した部分を書き換えると元配列にも反映されます。元配列を安全に残したいときは .copy() を明示します。
import numpy as np
x4 = np.random.randint(20, size=(3, 4))
print(x4)
# スライスは元配列を参照するビュー
x5 = x4[:2, :2]
print(x5)
# ビューを書き換えると元配列にも反映される
x5[0, 0] = 0
print(x5)
print(x4)
x4 = np.random.randint(20, size=(3, 4))
print(x4)
# copy() を使うと独立した配列になる
x6 = x4[:2, :2].copy()
print(x6)
# コピー先を書き換えても元配列は変わらない
x6[0, 0] = 0
print(x6)
print(x4)
配列を変形する
reshape() は配列の見え方を変える代表的なメソッドです。さらに np.newaxis を使うと、行ベクトルや列ベクトルを明示的に作れます。一次元化では、flatten() がコピーを返し、ravel() と reshape(-1) はビューとして扱われる点も押さえておくと便利です。
import numpy as np
# まずは 12 要素の一次元配列を作る
x5 = np.random.randint(0, 10, (12,))
print(x5)
print(x5.shape)
# 3 x 4 の形へ変える
x6 = x5.reshape(3, 4)
print(x6)
# reshape() の結果は元配列とメモリを共有することがある
x6[0, 0] = 0
print(x5)
# 一次元ベクトルを行ベクトルへ
x7 = x5.reshape(1, x5.shape[0])
print(x7)
print(x5[np.newaxis, :])
# 一次元ベクトルを列ベクトルへ
x8 = x5.reshape(x5.shape[0], 1)
print(x8)
print(x5[:, np.newaxis])
# 多次元配列を一次元へ
base = np.random.randint(0, 10, (3, 4))
print(base)
# flatten() はコピーを返す
flat = base.flatten()
flat[0] = 0
print(flat)
print(base)
# ravel() はビューとして振る舞うことが多い
raveled = base.ravel()
raveled[0] = 0
print(raveled)
print(base)
# reshape(-1) でも一次元へ変形できる
reshaped = base.reshape(-1)
reshaped[0] = 10
print(reshaped)
print(base)
reshape(-1, 1) と reshape(1, -1) を使い分ける
一次元配列を機械学習や行列演算へ渡すときは、ただの一次元配列 なのか、列ベクトル なのか、行ベクトル なのかを明示することが重要です。reshape(-1, 1) は 1 列の二次元配列、reshape(1, -1) は 1 行の二次元配列 を作ります。
ここでの -1 は、この軸の長さは NumPy 側で自動計算する という意味です。要素数さえ合っていれば、残りの長さを自動で埋めてくれます。
import numpy as np
base = np.arange(1, 7)
print(base)
print(base.shape)
# -1 は「残りの長さを自動計算する」という意味
# 1 列にしたいので、行数は 6 行へ自動計算される
column_vector = base.reshape(-1, 1)
print(column_vector)
print(column_vector.shape)
# こちらは 1 行へ並べ直す
# 列数が 6 列になるように自動計算される
row_vector = base.reshape(1, -1)
print(row_vector)
print(row_vector.shape)
# np.newaxis を使っても同じ形を作れる
print(base[:, np.newaxis].shape)
print(base[np.newaxis, :].shape)
# 行ベクトルと列ベクトルでは行列積の結果も変わる
print(row_vector @ column_vector) # 1 x 1 の内積になる
print(column_vector @ row_vector) # 6 x 6 の外積になる
配列を結合する
横方向の結合では hstack() や np.c_、縦方向の結合では vstack() や np.r_ が使えます。目的が「列を増やす」のか「行を増やす」のかを意識して使い分けます。
import numpy as np
x1 = np.array([
[1, 2, 3],
[4, 5, 6],
])
x2 = np.array([
[7, 8, 9],
[0, 1, 2],
])
# 横方向に結合して列数を増やす
x3 = np.hstack([x1, x2])
print(x3)
x3[0][0] = 0
print(x1)
# np.c_ も横方向の結合に使える
x4 = np.c_[x1, x2]
print(x4)
# 縦方向に結合して行数を増やす
x5 = np.vstack([x1, x2])
print(x5)
# np.r_ も縦方向の結合に使える
x6 = np.r_[x1, x2]
print(x6)
配列を分割する
ひとつの配列を区切って扱いたいときは split()、hsplit()、vsplit() を使います。Notebook では一次元配列の分割と、行列の列方向(横)・行方向(縦)の分割をそれぞれ試しています。
import numpy as np
x6 = np.arange(10)
print(x6)
# 2 と 7 の位置で 3 つに分割する
x1, x2, x3 = np.split(x6, [2, 7])
print(x1, x2, x3)
x7 = np.arange(1, 26).reshape(5, 5)
print(x7)
# 列方向(横)に 3 つへ分ける
left, middle, right = np.hsplit(x7, [2, 4])
print("left:\n", left)
print("middle:\n", middle)
print("right:\n", right)
# 行方向(縦)に 3 つへ分ける
upper, middle, lower = np.vsplit(x7, [2, 4])
print("upper:\n", upper)
print("middle:\n", middle)
print("lower:\n", lower)
NumPy の基本演算
この章では、NumPy でよく使う基本的な計算方法をまとめます。スカラーとの演算、行列積、ブロードキャスト、条件抽出が理解できると、かなり多くの前処理をループなしで書けるようになります。
ベクトル化演算
NumPy 配列は、数字ひとつとの四則演算も、配列同士の四則演算も、要素ごとにまとめて実行できます。Notebook では、基本の算術演算に加えて、絶対値、三角関数、指数、対数も確認しています。
import numpy as np
# スカラーとの演算は各要素へ一括適用される
x1 = np.arange(1, 6)
print(x1)
print("x1 + 5", x1 + 5)
print("x1 - 5", x1 - 5)
print("x1 * 5", x1 * 5)
print("x1 / 5", x1 / 5)
print("-x1", -x1)
print("x1 ** 2", x1 ** 2)
print("x1 // 2", x1 // 2)
print("x1 % 2", x1 % 2)
# 絶対値もまとめて計算できる
x2 = np.array([1, -1, 2, -2, 0])
print(abs(x2))
print(np.abs(x2))
# 三角関数
theta = np.linspace(0, np.pi, 3)
print("sin(theta)", np.sin(theta))
print("cos(theta)", np.cos(theta))
print("tan(theta)", np.tan(theta))
# 逆三角関数
x = [1, 0, -1]
print("arcsin(x)", np.arcsin(x))
print("arccos(x)", np.arccos(x))
print("arctan(x)", np.arctan(x))
# 指数と対数
x = np.arange(3)
print(np.exp(x))
x = np.array([1, 2, 4, 8, 10])
print("ln(x)", np.log(x))
print("log2(x)", np.log2(x))
print("log10(x)", np.log10(x))
# 配列同士でも同じ位置どうしで計算される
x1 = np.arange(1, 6)
x2 = np.arange(6, 11)
print("x1 + x2:", x1 + x2)
print("x1 - x2:", x1 - x2)
print("x1 * x2:", x1 * x2)
print("x1 / x2:", x1 / x2)
行列演算
二次元配列では、要素ごとの積と行列積を区別することが大切です。x * y は同じ位置同士の積、x.dot(y) や np.dot(x, y)、x @ y は行列積を意味します。
import numpy as np
# 転置を確認する
x = np.arange(9).reshape(3, 3)
print(x)
print(x.T)
x = np.array([
[1, 0],
[1, 1],
])
y = np.array([
[0, 1],
[1, 1],
])
# 行列積は dot()、np.dot()、@ で表せる
print(x.dot(y))
print(np.dot(x, y))
print(y.dot(x))
print(np.dot(y, x))
# x * y は要素ごとの積になる
print(x * y)
print(x @ y)
よく使う線形代数
NumPy では、行列式、逆行列、連立方程式、固有値、階数なども numpy.linalg で扱えます。機械学習や最適化の本格的な理論に進まなくても、この行列は正則か、連立方程式をどう解くか といった場面でよく使います。
import numpy as np
A = np.array([
[2.0, 1.0],
[1.0, 3.0],
])
b = np.array([5.0, 7.0])
print(A)
print(b)
# trace() は対角成分の和を返す
print(np.trace(A))
# matrix_rank() は行列の独立な軸の数を見るときに使う
print(np.linalg.matrix_rank(A))
# det() は行列式を返す
# 0 に近いと、逆行列が不安定だったり解けなかったりする
print(np.linalg.det(A))
# inv() は逆行列を返す
inverse_A = np.linalg.inv(A)
print(inverse_A)
# A @ inv(A) は単位行列に近い値になる
print(A @ inverse_A)
# solve() は A x = b の連立方程式を直接解く
# 逆行列を掛けるより、こちらの方が実務では自然なことが多い
solution = np.linalg.solve(A, b)
print(solution)
# eig() は固有値と固有ベクトルを返す
eigenvalues, eigenvectors = np.linalg.eig(A)
print(eigenvalues)
print(eigenvectors)
ブロードキャスト
ブロードキャストは、形状の一部が一致していれば、長さ 1 の軸を自動的に伸ばして計算する仕組みです。行列と行ベクトル、列ベクトルと行ベクトルの組み合わせで特に頻繁に使います。
import numpy as np
# スカラー 5 が各要素へ自動的に広がる
x = np.arange(3).reshape(1, 3)
print(x)
print(x + 5)
# 行ベクトルが各行へブロードキャストされる
x1 = np.ones((3, 3))
x2 = np.arange(3).reshape(1, 3)
print(x1 + x2)
# 列数が一致していれば行ごとに割れる
x3 = np.logspace(1, 10, 10, base=2).reshape(2, 5)
x4 = np.array([[1, 2, 4, 8, 16]])
print(x3 / x4)
# 列ベクトルと行ベクトルを足すと表になる
x5 = np.arange(3).reshape(3, 1)
x6 = np.arange(3).reshape(1, 3)
print(x5 + x6)
比較演算とブールマスク
比較演算の結果は真偽値配列として返ります。この配列をそのまま集計したり、条件に合う要素だけを抜き出したりできます。all() と any() も合わせて使うと、条件判定がかなり読みやすくなります。
import numpy as np
# まずは大きめの乱数行列で比較結果の形を見る
x1 = np.random.randint(100, size=(10, 10))
print(x1 > 50)
x2 = np.random.randint(10, size=(3, 4))
print(x2)
# 条件に合う場所は True になる
print(x2 > 5)
# True を数えると条件を満たす個数が分かる
print(np.sum(x2 > 5))
print(np.all(x2 > 0))
print(np.any(x2 == 6))
print(np.all(x2 < 9, axis=1))
# 複数条件を組み合わせたマスク
mask = (x2 < 9) & (x2 > 5)
print(mask)
print(np.sum(mask))
# マスクを使って条件に合う要素だけ抜き出す
print(x2[x2 > 5])
ファンシーインデックス
インデックスの配列を渡すと、欲しい位置だけをまとめて取得できます。一次元配列ではインデックス配列の形がそのまま結果の形に反映され、多次元配列では行配列と列配列を組み合わせて特定の座標だけを抜き出せます。
import numpy as np
x = np.random.randint(100, size=10)
print(x)
# 欲しい位置をリストで指定する
ind = [2, 6, 9]
print(x[ind])
# インデックス配列が 2 次元なら結果も 2 次元になる
ind = np.array([
[1, 0],
[2, 3],
])
print(x[ind])
x = np.arange(12).reshape(3, 4)
print(x)
# 行インデックスと列インデックスを組み合わせる
row = np.array([0, 1, 2])
col = np.array([1, 3, 0])
print(x[row, col])
print(row[:, np.newaxis])
# 行ごとに複数列をまとめて取り出す
print(x[row[:, np.newaxis], col])
その他のよく使う NumPy 関数
最後に、並べ替え、最大値・最小値、合計、平均など、日常的によく使う関数をまとめて確認します。ここは単独でもよく使いますが、前章までの配列操作と組み合わせると分析コード全体がかなり短くなります。
並べ替え
np.sort() は並べ替えた新しい配列を返し、x.sort() は元配列自体を並べ替えます。argsort() を使うと、並べ替え後の順序を与えるインデックスが得られます。
import numpy as np
x = np.random.randint(20, 50, size=10)
print(x)
# 並べ替えた新しい配列を返す
print(np.sort(x))
print(x)
# 元配列そのものを並べ替える
x.sort()
print(x)
x = np.random.randint(20, 50, size=10)
print(x)
# 並べ替え後の順番を表す添字を返す
print(np.argsort(x))
最大値と最小値
値そのものを知りたいときは max() と min()、位置を知りたいときは argmax() と argmin() を使います。
import numpy as np
x = np.random.randint(20, 50, size=10)
print(x)
# 値と位置をそれぞれ確認する
print("max:", np.max(x))
print("min:", np.min(x))
print("max_index:", np.argmax(x))
print("min_index:", np.argmin(x))
総和と総積
合計は sum()、積は prod() で求めます。二次元以上では axis= を指定すると、行方向(縦)や列方向(横)ごとの集計もできます。
import numpy as np
x = np.arange(1, 6)
print(x)
# 一次元配列の合計と積
print(x.sum())
print(np.sum(x))
x1 = np.arange(6).reshape(2, 3)
print(x1)
# axis=1 は行ごと、axis=0 は列ごとの集計
print(np.sum(x1, axis=1))
print(np.sum(x1, axis=0))
print(np.sum(x1))
print(x.prod())
print(np.prod(x))
中央値、平均、分散、標準偏差
代表値を見るときは、median()、mean()、var()、std() をまとめて使えるようにしておくと便利です。Notebook では、正規乱数を作ってヒストグラムを描き、その分布に対して各統計量を確認しています。
import matplotlib.pyplot as plt
import numpy as np
# 正規乱数をたくさん作って分布を見る
x = np.random.normal(0, 1, size=10000)
plt.hist(x, bins=50)
plt.show()
# 代表値や散らばり具合をまとめて確認する
print(np.median(x))
print(x.mean())
print(np.mean(x))
print(x.var())
print(np.var(x))
print(x.std())
print(np.std(x))
まとめ
NumPy を最初に学ぶときは、関数名をバラバラに覚えるよりも、次の流れでつなげて覚えると定着しやすくなります。
-
np.array()やzeros()などで配列を作る。 -
shape、ndim、dtypeを確認して、配列の形と型を把握する。 - インデックス、スライス、
reshape()で配列の見え方をコントロールする。 - 四則演算、ブロードキャスト、ブールマスクでループを書かずに処理する。
-
sum()、mean()、sort()などの基本的な関数で最後に集計する。
この順番で何度か手を動かすと、Pandas、scikit-learn、PyTorch に進んだあとも、「いま扱っているのはどんな形の数値配列か」を意識しながらコードを読めるようになります。