Step 19:NumPy配列の操作

🔧 ステップ19: NumPy配列の操作

配列の形を変えたり、結合したり、自由自在に操作しよう!

ステップ18では、NumPy配列の基本を学びました。今回は、配列を自在に操作する方法を学びます。形を変えたり、複数の配列を結合したり、分割したり…実際のデータ分析では、これらの操作が頻繁に必要になります。

📖 このステップで学ぶこと

・配列の形状(shape)の確認方法

・reshape(リシェイプ)で配列の形を変える

・配列の結合(vstack、hstack)

・配列の分割(vsplit、hsplit)

・転置(transpose)で行と列を入れ替える

学習時間の目安: 2.5〜3時間

🎯 1. 配列の形状を理解しよう

まず、配列の「形」について復習しましょう。

🔰 shapeで形を確認

配列のshape(形状)は、データがどんな構造になっているかを表します。

コード:1次元と2次元の形を確認

import numpy as np

# 1次元配列
arr_1d = np.array([1, 2, 3, 4, 5])
print("【1次元配列】")
print(f"配列: {arr_1d}")
print(f"形状: {arr_1d.shape}")
print()

# 2次元配列
arr_2d = np.array([
    [1, 2, 3],
    [4, 5, 6]
])
print("【2次元配列】")
print(arr_2d)
print(f"形状: {arr_2d.shape}")

※ 画面が小さい場合は、コードブロックを横にスクロールできます

実行結果

【1次元配列】
配列: [1 2 3 4 5]
形状: (5,)

【2次元配列】
[[1 2 3]
 [4 5 6]]
形状: (2, 3)

📌 shapeの読み方

shape 意味 イメージ
(5,) 1次元、要素5個 横一列のデータ
(2, 3) 2行3列 2行×3列の表
(3, 4, 2) 3次元配列 3階建ての4行2列

📘 配列のサイズ情報をまとめて確認

コード:配列の詳細情報を表示

import numpy as np

arr = np.array([
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11, 12]
])

print("配列:")
print(arr)
print()
print(f"形状(shape): {arr.shape}")
print(f"次元数(ndim): {arr.ndim}")
print(f"要素数(size): {arr.size}")
print(f"行数: {arr.shape[0]}")
print(f"列数: {arr.shape[1]}")

※ 画面が小さい場合は、コードブロックを横にスクロールできます

実行結果

配列:
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]

形状(shape): (3, 4)
次元数(ndim): 2
要素数(size): 12
行数: 3
列数: 4

💡 コードの解説

arr.shape[0]

・shapeの最初の要素 = 行数

・(3, 4)なら shape[0] は 3

arr.shape[1]

・shapeの2番目の要素 = 列数

・(3, 4)なら shape[1] は 4

🔄 2. reshape – 配列の形を変える

配列の形を変えるreshape(リシェイプ)を学びましょう。データの「並べ方」を変える操作です。

🔰 1次元から2次元へ

reshape()を使うと、配列の形を変えられます。要素の数は変わりません。

📝 書き方:reshape()

配列.reshape(行数, 列数)

元の配列を、指定した行数×列数の形に変形します。

条件:元の要素数 = 新しい行数 × 新しい列数

コード:1次元配列を2次元に変形

import numpy as np

# 1次元配列を作成(要素6個)
arr = np.array([1, 2, 3, 4, 5, 6])
print(f"元の配列: {arr}")
print(f"形状: {arr.shape}")
print()

# 2行3列に変形
arr_2x3 = arr.reshape(2, 3)
print("2行3列に変形:")
print(arr_2x3)
print(f"形状: {arr_2x3.shape}")
print()

# 3行2列に変形
arr_3x2 = arr.reshape(3, 2)
print("3行2列に変形:")
print(arr_3x2)
print(f"形状: {arr_3x2.shape}")

※ 画面が小さい場合は、コードブロックを横にスクロールできます

実行結果

元の配列: [1 2 3 4 5 6]
形状: (6,)

2行3列に変形:
[[1 2 3]
 [4 5 6]]
形状: (2, 3)

3行2列に変形:
[[1 2]
 [3 4]
 [5 6]]
形状: (3, 2)

💡 reshapeの仕組み

元の配列 [1, 2, 3, 4, 5, 6] が、左上から右に向かって順番に詰められていきます:

2行3列の場合:

 1行目:1, 2, 3

 2行目:4, 5, 6

⚠️ reshapeの条件

元の要素数と新しい形の要素数は同じでなければなりません。

OK:6個の要素 → (2, 3) または (3, 2) → 2×3=6、3×2=6

NG:6個の要素 → (2, 4) → 2×4=8 ≠ 6 → エラー

📘 -1を使った自動計算(便利!)

reshape()で-1を使うと、NumPyが自動的にサイズを計算してくれます。

📝 書き方:-1を使ったreshape

配列.reshape(3, -1) → 3行で、列数は自動計算

配列.reshape(-1, 4) → 4列で、行数は自動計算

配列.reshape(-1) → 1次元に変換

コード:-1で自動計算

import numpy as np

arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
print(f"元の配列: {arr}")
print(f"要素数: {arr.size}")
print()

# 3行で、列数は自動計算(12÷3=4列)
arr_3rows = arr.reshape(3, -1)
print("3行、列数自動:")
print(arr_3rows)
print(f"形状: {arr_3rows.shape}")
print()

# 4列で、行数は自動計算(12÷4=3行)
arr_4cols = arr.reshape(-1, 4)
print("行数自動、4列:")
print(arr_4cols)
print(f"形状: {arr_4cols.shape}")

※ 画面が小さい場合は、コードブロックを横にスクロールできます

実行結果

元の配列: [ 1  2  3  4  5  6  7  8  9 10 11 12]
要素数: 12

3行、列数自動:
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
形状: (3, 4)

行数自動、4列:
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
形状: (3, 4)

💡 -1 はとても便利!

「3行にしたいけど、列数は計算が面倒…」というときに使います。

NumPyが自動で計算してくれるので、ミスが減ります。

実務では頻繁に使うテクニックです!

📘 flattenで1次元に戻す

2次元配列を1次元に戻すには、flatten()を使います。

コード:2次元を1次元に変換

import numpy as np

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

print("2次元配列:")
print(arr_2d)
print()

# flatten()で1次元に変換
arr_1d = arr_2d.flatten()
print(f"1次元に変換: {arr_1d}")

# reshape(-1)でも同じ結果
arr_1d_v2 = arr_2d.reshape(-1)
print(f"reshape(-1): {arr_1d_v2}")

※ 画面が小さい場合は、コードブロックを横にスクロールできます

実行結果

2次元配列:
[[1 2 3]
 [4 5 6]
 [7 8 9]]

1次元に変換: [1 2 3 4 5 6 7 8 9]
reshape(-1): [1 2 3 4 5 6 7 8 9]

💡 flatten()とreshape(-1)の違い

flatten():常に新しい配列のコピーを作る

reshape(-1):元の配列と同じメモリを参照することがある

通常はどちらを使っても問題ありませんが、flatten()の方が安全です。

➕ 3. 配列の結合

複数の配列を1つにまとめる方法を学びましょう。

🔰 縦に結合 – vstack(垂直方向)

np.vstack()で配列を縦(垂直)に結合できます。「行を追加する」イメージです。

📝 書き方:vstack

np.vstack([配列1, 配列2, …])

vstack = Vertical Stack(垂直に積む)

配列を下に追加していくイメージです。

コード:配列を縦に結合

import numpy as np

arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])

print(f"配列1: {arr1}")
print(f"配列2: {arr2}")
print()

# 縦に結合
result = np.vstack([arr1, arr2])
print("縦に結合(vstack):")
print(result)
print(f"形状: {result.shape}")

※ 画面が小さい場合は、コードブロックを横にスクロールできます

実行結果

配列1: [1 2 3]
配列2: [4 5 6]

縦に結合(vstack):
[[1 2 3]
 [4 5 6]]
形状: (2, 3)

💡 vstackのイメージ

2つの1次元配列が、2次元配列の各行になりました:

 [1, 2, 3] → 1行目

 [4, 5, 6] → 2行目

📘 横に結合 – hstack(水平方向)

np.hstack()で配列を横(水平)に結合できます。「列を追加する」イメージです。

📝 書き方:hstack

np.hstack([配列1, 配列2, …])

hstack = Horizontal Stack(水平に並べる)

配列を右に追加していくイメージです。

コード:配列を横に結合

import numpy as np

arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])

print(f"配列1: {arr1}")
print(f"配列2: {arr2}")
print()

# 横に結合
result = np.hstack([arr1, arr2])
print(f"横に結合(hstack): {result}")
print(f"形状: {result.shape}")

※ 画面が小さい場合は、コードブロックを横にスクロールできます

実行結果

配列1: [1 2 3]
配列2: [4 5 6]

横に結合(hstack): [1 2 3 4 5 6]
形状: (6,)

📘 2次元配列の結合

2次元配列同士も同じように結合できます。

コード:2次元配列の結合

import numpy as np

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

arr2 = np.array([
    [5, 6],
    [7, 8]
])

print("配列1:")
print(arr1)
print("\n配列2:")
print(arr2)

# 縦に結合(行を追加)
v_result = np.vstack([arr1, arr2])
print("\n縦に結合(vstack):")
print(v_result)
print(f"形状: {v_result.shape}")

# 横に結合(列を追加)
h_result = np.hstack([arr1, arr2])
print("\n横に結合(hstack):")
print(h_result)
print(f"形状: {h_result.shape}")

※ 画面が小さい場合は、コードブロックを横にスクロールできます

実行結果

配列1:
[[1 2]
 [3 4]]

配列2:
[[5 6]
 [7 8]]

縦に結合(vstack):
[[1 2]
 [3 4]
 [5 6]
 [7 8]]
形状: (4, 2)

横に結合(hstack):
[[1 2 5 6]
 [3 4 7 8]]
形状: (2, 4)

📌 vstackとhstackの覚え方

関数 意味 イメージ
vstack Vertical(垂直) 縦に積む → 行が増える
hstack Horizontal(水平) 横に並べる → 列が増える

📘 concatenate – より柔軟な結合

np.concatenate()を使うと、結合する方向をaxisで指定できます。

📝 書き方:concatenate

np.concatenate([配列1, 配列2], axis=0) → 縦方向(vstackと同じ)

np.concatenate([配列1, 配列2], axis=1) → 横方向(hstackと同じ)

axis(軸): 0 = 縦方向、1 = 横方向

コード:concatenateで結合方向を指定

import numpy as np

arr1 = np.array([
    [1, 2, 3],
    [4, 5, 6]
])

arr2 = np.array([
    [7, 8, 9],
    [10, 11, 12]
])

# axis=0 で縦方向に結合(vstackと同じ)
result_v = np.concatenate([arr1, arr2], axis=0)
print("縦に結合(axis=0):")
print(result_v)
print()

# axis=1 で横方向に結合(hstackと同じ)
result_h = np.concatenate([arr1, arr2], axis=1)
print("横に結合(axis=1):")
print(result_h)

※ 画面が小さい場合は、コードブロックを横にスクロールできます

実行結果

縦に結合(axis=0):
[[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]]

横に結合(axis=1):
[[ 1  2  3  7  8  9]
 [ 4  5  6 10 11 12]]

💡 vstack/hstack と concatenate の使い分け

vstack/hstack:単純な縦・横結合に便利。覚えやすい

concatenate:3次元以上の配列や、プログラムで方向を切り替えたいときに便利

最初はvstack/hstackを使い、慣れてきたらconcatenateも使ってみましょう。

✂️ 4. 配列の分割

結合の逆で、1つの配列を複数に分ける方法を学びましょう。

🔰 縦に分割 – vsplit

np.vsplit()で配列を縦方向(水平線)で分割できます。

📝 書き方:vsplit

np.vsplit(配列, 分割数)

配列を縦方向に、指定した数に等分します。

条件:行数が分割数で割り切れること

コード:配列を縦に分割

import numpy as np

arr = np.array([
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
    [10, 11, 12]
])

print("元の配列:")
print(arr)
print(f"形状: {arr.shape}")
print()

# 2つに分割
part1, part2 = np.vsplit(arr, 2)

print("前半(part1):")
print(part1)
print()
print("後半(part2):")
print(part2)

※ 画面が小さい場合は、コードブロックを横にスクロールできます

実行結果

元の配列:
[[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]]
形状: (4, 3)

前半(part1):
[[1 2 3]
 [4 5 6]]

後半(part2):
[[ 7  8  9]
 [10 11 12]]

💡 vsplitのイメージ

4行の配列を2分割 → 各2行ずつの配列が2つできます。

「上半分」と「下半分」に分けるイメージです。

📘 横に分割 – hsplit

np.hsplit()で配列を横方向(垂直線)で分割できます。

コード:配列を横に分割

import numpy as np

arr = np.array([
    [1, 2, 3, 4, 5, 6],
    [7, 8, 9, 10, 11, 12]
])

print("元の配列:")
print(arr)
print(f"形状: {arr.shape}")
print()

# 3つに分割(6列 ÷ 3 = 各2列)
part1, part2, part3 = np.hsplit(arr, 3)

print("1つ目:")
print(part1)
print()
print("2つ目:")
print(part2)
print()
print("3つ目:")
print(part3)

※ 画面が小さい場合は、コードブロックを横にスクロールできます

実行結果

元の配列:
[[ 1  2  3  4  5  6]
 [ 7  8  9 10 11 12]]
形状: (2, 6)

1つ目:
[[1 2]
 [7 8]]

2つ目:
[[ 3  4]
 [ 9 10]]

3つ目:
[[ 5  6]
 [11 12]]

📘 指定した位置で分割 – split

np.split()を使うと、任意の位置で分割できます。

📝 書き方:split(位置指定)

np.split(配列, [位置1, 位置2, …])

指定した位置で配列を切り分けます。

位置は「その前で切る」イメージです。

コード:指定位置で分割

import numpy as np

arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])

print(f"元の配列: {arr}")
print()

# インデックス3と7の位置で分割
# [1,2,3] | [4,5,6,7] | [8,9,10]
part1, part2, part3 = np.split(arr, [3, 7])

print(f"0〜3番目(インデックス0-2):  {part1}")
print(f"3〜7番目(インデックス3-6):  {part2}")
print(f"7番目以降(インデックス7-9): {part3}")

※ 画面が小さい場合は、コードブロックを横にスクロールできます

実行結果

元の配列: [ 1  2  3  4  5  6  7  8  9 10]

0〜3番目(インデックス0-2):  [1 2 3]
3〜7番目(インデックス3-6):  [4 5 6 7]
7番目以降(インデックス7-9): [ 8  9 10]

💡 splitの位置指定の考え方

[3, 7]を指定すると:

・0〜2番目(3個)

・3〜6番目(4個)

・7〜9番目(3個)

の3つに分かれます。「その位置の前で切る」と覚えましょう。

🔀 5. 転置(transpose)

配列の行と列を入れ替える操作を「転置(てんち)」と言います。

🔰 転置とは?

転置は、2次元配列の行と列を入れ替える操作です。Excelで「行列の入れ替え」をするのと同じです。

📝 書き方:転置

配列.T

Tは「Transpose(転置)」の頭文字です。

とても短く書けて便利です。

コード:行と列を入れ替える

import numpy as np

arr = np.array([
    [1, 2, 3],
    [4, 5, 6]
])

print("元の配列(2行3列):")
print(arr)
print(f"形状: {arr.shape}")
print()

# 転置
arr_t = arr.T
print("転置後(3行2列):")
print(arr_t)
print(f"形状: {arr_t.shape}")

※ 画面が小さい場合は、コードブロックを横にスクロールできます

実行結果

元の配列(2行3列):
[[1 2 3]
 [4 5 6]]
形状: (2, 3)

転置後(3行2列):
[[1 4]
 [2 5]
 [3 6]]
形状: (3, 2)

💡 転置のイメージ

元の配列の1行目が、転置後の1列目になります:

 元の1行目 [1, 2, 3] → 転置後の1列目 [1, 2, 3]

 元の2行目 [4, 5, 6] → 転置後の2列目 [4, 5, 6]

表を「斜め45度に傾ける」イメージです。

📘 実践例:データの整形

転置は、データの見方を変えたいときに便利です。

コード:生徒×科目 → 科目×生徒 に変換

import numpy as np

# 生徒3人の国語、数学、英語の点数
# 行 = 生徒、列 = 科目
scores = np.array([
    [85, 90, 78],  # 太郎
    [92, 88, 95],  # 花子
    [78, 85, 82]   # 次郎
])

print("元のデータ(生徒×科目):")
print(scores)
print("→ 各行が1人の生徒の全科目の点数")
print()

# 転置して科目×生徒に変換
scores_t = scores.T
print("転置後(科目×生徒):")
print(scores_t)
print("→ 各行が1科目の全生徒の点数")
print()

# 各科目の平均点を計算(転置後なら各行の平均)
subjects = ["国語", "数学", "英語"]
print("各科目の平均点:")
for i, subject in enumerate(subjects):
    avg = scores_t[i].mean()
    print(f"  {subject}: {avg:.1f}点")

※ 画面が小さい場合は、コードブロックを横にスクロールできます

実行結果

元のデータ(生徒×科目):
[[85 90 78]
 [92 88 95]
 [78 85 82]]
→ 各行が1人の生徒の全科目の点数

転置後(科目×生徒):
[[85 92 78]
 [90 88 85]
 [78 95 82]]
→ 各行が1科目の全生徒の点数

各科目の平均点:
  国語: 85.0点
  数学: 87.7点
  英語: 85.0点

💡 転置が便利な場面

・「生徒ごと」のデータを「科目ごと」に変えたいとき

・「店舗ごと」のデータを「日付ごと」に変えたいとき

・行列の計算で形を合わせたいとき

📊 6. 実践例:データの整形

ここまで学んだ操作を使って、実際のデータ分析でよくある操作を練習しましょう。

📘 例1:月次売上データの整形

コード:12ヶ月のデータを四半期別に整形

import numpy as np

# 12ヶ月の売上データ(1次元、単位:万円)
monthly_sales = np.array([
    120, 135, 150,   # 1-3月(Q1)
    145, 160, 175,   # 4-6月(Q2)
    180, 190, 185,   # 7-9月(Q3)
    170, 160, 200    # 10-12月(Q4)
])

print(f"月次売上データ: {monthly_sales}")
print(f"要素数: {monthly_sales.size}")
print()

# 4四半期 × 3ヶ月 に整形
quarterly = monthly_sales.reshape(4, 3)
print("四半期別に整形(4行3列):")
print(quarterly)
print()

# 各四半期の合計を計算
print("四半期別の売上合計:")
quarters = ["Q1(1-3月)", "Q2(4-6月)", "Q3(7-9月)", "Q4(10-12月)"]
for i, q in enumerate(quarters):
    total = quarterly[i].sum()
    print(f"  {q}: {total}万円")

※ 画面が小さい場合は、コードブロックを横にスクロールできます

実行結果

月次売上データ: [120 135 150 145 160 175 180 190 185 170 160 200]
要素数: 12

四半期別に整形(4行3列):
[[120 135 150]
 [145 160 175]
 [180 190 185]
 [170 160 200]]

四半期別の売上合計:
  Q1(1-3月): 405万円
  Q2(4-6月): 480万円
  Q3(7-9月): 555万円
  Q4(10-12月): 530万円

📘 例2:複数店舗のデータ結合

コード:3店舗のデータを結合して分析

import numpy as np

# 各店舗の1週間の売上(単位:千円)
store_a = np.array([50, 62, 58, 71, 65, 88, 92])
store_b = np.array([45, 55, 60, 68, 70, 85, 90])
store_c = np.array([52, 58, 55, 65, 68, 82, 88])

print("店舗A:", store_a)
print("店舗B:", store_b)
print("店舗C:", store_c)
print()

# 縦に結合して、店舗×日 の2次元配列に
all_stores = np.vstack([store_a, store_b, store_c])
print("全店舗のデータ(縦に結合):")
print(all_stores)
print(f"形状: {all_stores.shape}")
print()

# 各店舗の週間合計(行ごとの合計)
print("各店舗の週間合計:")
stores = ["店舗A", "店舗B", "店舗C"]
for i, store in enumerate(stores):
    total = all_stores[i].sum()
    print(f"  {store}: {total}千円")
print()

# 各曜日の全店舗合計(列ごとの合計)
daily_total = all_stores.sum(axis=0)
days = ["月", "火", "水", "木", "金", "土", "日"]
print("曜日別の全店舗合計:")
for day, total in zip(days, daily_total):
    print(f"  {day}曜: {total}千円")

※ 画面が小さい場合は、コードブロックを横にスクロールできます

実行結果

店舗A: [50 62 58 71 65 88 92]
店舗B: [45 55 60 68 70 85 90]
店舗C: [52 58 55 65 68 82 88]

全店舗のデータ(縦に結合):
[[50 62 58 71 65 88 92]
 [45 55 60 68 70 85 90]
 [52 58 55 65 68 82 88]]
形状: (3, 7)

各店舗の週間合計:
  店舗A: 486千円
  店舗B: 473千円
  店舗C: 468千円

曜日別の全店舗合計:
  月曜: 147千円
  火曜: 175千円
  水曜: 173千円
  木曜: 204千円
  金曜: 203千円
  土曜: 255千円
  日曜: 270千円

💡 コードの解説

all_stores.sum(axis=0)

・axis=0 は「縦方向に合計」という意味

・各列(日ごと)の全店舗合計が計算されます

zip(days, daily_total)

・2つのリストを同時にループで回すときに使います

・day と total が同時に取り出されます

📝 練習問題

ここまで学んだことを、実際に手を動かして確認しましょう。

問題1:配列の形を変える(初級)

📋 問題

1から12までの整数を含む1次元配列を作成し、3行4列の2次元配列に変形してください。

解答例を見る

コード

import numpy as np

# 1次元配列を作成
arr = np.arange(1, 13)
print(f"元の配列: {arr}")
print(f"形状: {arr.shape}")

# 3行4列に変形
arr_2d = arr.reshape(3, 4)
print("\n3行4列に変形:")
print(arr_2d)
print(f"形状: {arr_2d.shape}")

※ 画面が小さい場合は、コードブロックを横にスクロールできます

実行結果

元の配列: [ 1  2  3  4  5  6  7  8  9 10 11 12]
形状: (12,)

3行4列に変形:
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
形状: (3, 4)

問題2:配列の結合(初級)

📋 問題

[1, 2, 3]という配列と[4, 5, 6]という配列を作成し、縦に結合してください。

解答例を見る

コード

import numpy as np

arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])

# 縦に結合
result = np.vstack([arr1, arr2])

print(f"配列1: {arr1}")
print(f"配列2: {arr2}")
print("\n縦に結合:")
print(result)
print(f"形状: {result.shape}")

※ 画面が小さい場合は、コードブロックを横にスクロールできます

実行結果

配列1: [1 2 3]
配列2: [4 5 6]

縦に結合:
[[1 2 3]
 [4 5 6]]
形状: (2, 3)

問題3:転置を使った計算(中級)

📋 問題

以下の2行3列の配列を転置して、各行(元の列)の合計を計算してください。

arr = [[10, 20, 30], [40, 50, 60]]

解答例を見る

コード

import numpy as np

arr = np.array([
    [10, 20, 30],
    [40, 50, 60]
])

print("元の配列(2行3列):")
print(arr)

# 転置
arr_t = arr.T
print("\n転置後(3行2列):")
print(arr_t)

# 各行の合計(元の各列の合計)
print("\n各行の合計:")
for i, row in enumerate(arr_t):
    print(f"  {i+1}行目: {row} → 合計 {row.sum()}")

※ 画面が小さい場合は、コードブロックを横にスクロールできます

実行結果

元の配列(2行3列):
[[10 20 30]
 [40 50 60]]

転置後(3行2列):
[[10 40]
 [20 50]
 [30 60]]

各行の合計:
  1行目: [10 40] → 合計 50
  2行目: [20 50] → 合計 70
  3行目: [30 60] → 合計 90

問題4:配列の分割(中級)

📋 問題

1から20までの配列を作成し、前半10個と後半10個に分割してください。それぞれの合計も表示してください。

解答例を見る

コード

import numpy as np

# 1から20までの配列
arr = np.arange(1, 21)
print(f"元の配列: {arr}")

# 2つに分割
first_half, second_half = np.split(arr, 2)

print(f"\n前半: {first_half}")
print(f"前半の合計: {first_half.sum()}")

print(f"\n後半: {second_half}")
print(f"後半の合計: {second_half.sum()}")

※ 画面が小さい場合は、コードブロックを横にスクロールできます

実行結果

元の配列: [ 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20]

前半: [ 1  2  3  4  5  6  7  8  9 10]
前半の合計: 55

後半: [11 12 13 14 15 16 17 18 19 20]
後半の合計: 155

問題5:複数の配列を結合して分析(上級)

📋 問題

3つの店舗の売上データ(各5日分)があります。これらを結合して3行5列の配列を作り、各店舗の平均売上と各日の合計売上を計算してください。

店舗A = [120, 135, 150, 145, 160]
店舗B = [110, 125, 140, 138, 155]
店舗C = [115, 130, 145, 142, 158]

解答例を見る

コード

import numpy as np

store_a = np.array([120, 135, 150, 145, 160])
store_b = np.array([110, 125, 140, 138, 155])
store_c = np.array([115, 130, 145, 142, 158])

# 縦に結合
all_stores = np.vstack([store_a, store_b, store_c])
print("全店舗のデータ:")
print(all_stores)

# 各店舗の平均(行ごとの平均 → axis=1)
print("\n各店舗の平均売上:")
stores = ["店舗A", "店舗B", "店舗C"]
for i, store in enumerate(stores):
    avg = all_stores[i].mean()
    print(f"  {store}: {avg:.1f}千円")

# 各日の合計(列ごとの合計 → axis=0)
daily_total = all_stores.sum(axis=0)
print("\n各日の合計売上:")
for i, total in enumerate(daily_total, 1):
    print(f"  {i}日目: {total}千円")

※ 画面が小さい場合は、コードブロックを横にスクロールできます

実行結果

全店舗のデータ:
[[120 135 150 145 160]
 [110 125 140 138 155]
 [115 130 145 142 158]]

各店舗の平均売上:
  店舗A: 142.0千円
  店舗B: 133.6千円
  店舗C: 138.0千円

各日の合計売上:
  1日目: 345千円
  2日目: 390千円
  3日目: 435千円
  4日目: 425千円
  5日目: 473千円

問題6:複雑な整形操作(上級)

📋 問題

1から24までの連続した数値を含む配列を作成し、以下の操作を行ってください:

1. 4行6列に整形

2. 転置して6行4列に変換

3. 2つに分割(前半3行、後半3行)

4. それぞれの平均値を計算

解答例を見る

コード

import numpy as np

# 1. 1から24までの配列を作成
arr = np.arange(1, 25)
print(f"元の配列: {arr}")

# 2. 4行6列に整形
arr_4x6 = arr.reshape(4, 6)
print("\n4行6列に整形:")
print(arr_4x6)

# 3. 転置して6行4列に
arr_6x4 = arr_4x6.T
print("\n転置(6行4列):")
print(arr_6x4)

# 4. 2つに分割(前半3行、後半3行)
first_half, second_half = np.vsplit(arr_6x4, 2)

print("\n前半3行:")
print(first_half)
print(f"平均: {first_half.mean()}")

print("\n後半3行:")
print(second_half)
print(f"平均: {second_half.mean()}")

※ 画面が小さい場合は、コードブロックを横にスクロールできます

実行結果

元の配列: [ 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24]

4行6列に整形:
[[ 1  2  3  4  5  6]
 [ 7  8  9 10 11 12]
 [13 14 15 16 17 18]
 [19 20 21 22 23 24]]

転置(6行4列):
[[ 1  7 13 19]
 [ 2  8 14 20]
 [ 3  9 15 21]
 [ 4 10 16 22]
 [ 5 11 17 23]
 [ 6 12 18 24]]

前半3行:
[[ 1  7 13 19]
 [ 2  8 14 20]
 [ 3  9 15 21]]
平均: 11.0

後半3行:
[[ 4 10 16 22]
 [ 5 11 17 23]
 [ 6 12 18 24]]
平均: 14.0

🎯 このステップのまとめ

✅ 学んだこと

shapeで配列の形状(行数×列数)を確認できる

reshape()で配列の形を変更できる

-1を使うとサイズを自動計算してくれる

vstack/hstackで配列を縦/横に結合できる

vsplit/hsplitで配列を縦/横に分割できる

.Tで転置(行と列の入れ替え)ができる

flatten()で1次元に変換できる

💡 次のステップに進む前に確認

以下のことができるようになったか確認しましょう:

□ reshape()で配列の形を変えられる

□ vstack/hstackで配列を結合できる

□ vsplit/hsplitで配列を分割できる

□ .Tで転置ができる

□ axis(軸)の概念が理解できている

これらができたら、次のステップに進みましょう!

❓ よくある質問

Q1: reshapeで-1を使うとどうなりますか?

A: -1を指定すると、NumPyが自動的にサイズを計算してくれます。例えば12個の要素をreshape(3, -1)とすると、3行で列数は自動的に4になります(12÷3=4)。計算が面倒なときにとても便利なので、積極的に使いましょう!

Q2: vstackとhstackはどう使い分けますか?

A: データを追加する方向で決めます。vstackは新しい行を追加(下に追加)、hstackは新しい列を追加(右に追加)します。「新しいデータ(行)を追加」ならvstack、「新しい項目(列)を追加」ならhstackと覚えましょう。

Q3: 転置はいつ使いますか?

A: データの見方を変えたい時に使います。例えば、「生徒ごとの点数」を「科目ごとの点数」に変えたい時です。Excelで「行列の入れ替え」をするのと同じ操作です。データ分析では頻繁に使います。

Q4: flattenとreshape(-1)の違いは?

A: どちらも1次元に変換しますが、flatten()は常に新しい配列のコピーを作るのに対し、reshape(-1)は元の配列と同じメモリを参照する場合があるという違いがあります。安全性を重視するならflatten()、メモリ効率を重視するならreshape(-1)を使いましょう。

Q5: 配列の結合や分割で形が合わない時は?

A: エラーが出ます。vstackなら列数が同じhstackなら行数が同じである必要があります。まずはshapeで形を確認し、必要ならreshape()で調整しましょう。

Q6: axis=0とaxis=1の違いは?

A: axis=0は「縦方向」(行をまたぐ)axis=1は「横方向」(列をまたぐ)です。例えばsum(axis=0)は「各列の合計」、sum(axis=1)は「各行の合計」になります。「axis=0は行を圧縮」「axis=1は列を圧縮」と覚えると分かりやすいです。

📝

学習メモ

Pythonデータ分析入門 - Step 19

📋 過去のメモ一覧
#artnasekai #学習メモ
LINE