Step 20:NumPyで統計計算

📈 ステップ20: NumPyで統計計算

平均、中央値、標準偏差…NumPyで簡単に統計量を計算しよう!

Part 3で学んだ統計計算を、NumPyを使って簡単に行う方法を学びます。自分で関数を作らなくても、NumPyには便利な統計関数がたくさん用意されています。

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

・平均値(mean)、中央値(median)、標準偏差(std)

・最大値(max)、最小値(min)とその位置

・合計(sum)と累積和(cumsum)

・パーセンタイル(percentile)と四分位数

・2次元配列での統計計算(axis指定)

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

🎯 1. 基本的な統計量

データ分析で最もよく使う3つの統計量から始めましょう。

🔰 平均値を計算 – mean()

mean()(ミーン)は、データの平均値を計算します。「全部足して、個数で割る」計算を自動でやってくれます。

📝 書き方:平均値の計算

np.mean(配列)

配列.mean()

どちらの書き方でも同じ結果になります。

コード:平均値を計算する

import numpy as np

# テストの点数データ
scores = np.array([85, 92, 78, 95, 88, 90, 82])

# 平均値を計算(2つの方法)
average1 = np.mean(scores)    # 方法1: np.mean()
average2 = scores.mean()      # 方法2: 配列.mean()

print(f"テストの点数: {scores}")
print(f"平均点(np.mean): {average1}")
print(f"平均点(.mean): {average2}")
print(f"平均点(小数第1位): {round(average1, 1)}")

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

実行結果

テストの点数: [85 92 78 95 88 90 82]
平均点(np.mean): 87.14285714285714
平均点(.mean): 87.14285714285714
平均点(小数第1位): 87.1

💡 コードの解説

np.mean(scores)

・NumPyの関数として平均を計算

・(85+92+78+95+88+90+82) ÷ 7 = 87.14… を自動計算

round(average1, 1)

・小数第1位で四捨五入

・見やすい数値にするときに使います

📘 中央値を計算 – median()

median()(メディアン)は、データを小さい順に並べた時の真ん中の値を返します。

📝 書き方:中央値の計算

np.median(配列)

※ 配列.median()という書き方はありません。必ずnp.median()を使います。

コード:中央値を計算する

import numpy as np

scores = np.array([85, 92, 78, 95, 88, 90, 82])

# 中央値を計算
median_value = np.median(scores)

# 並べ替えて確認
sorted_scores = np.sort(scores)

print(f"元の点数: {scores}")
print(f"並べ替え: {sorted_scores}")
print(f"中央値: {median_value}")

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

実行結果

元の点数: [85 92 78 95 88 90 82]
並べ替え: [78 82 85 88 90 92 95]
中央値: 88.0

💡 中央値の求め方

並べ替え: [78, 82, 85, 88, 90, 92, 95]

7個のデータなので、4番目(真ん中)の88が中央値です。

データが偶数個の場合は、真ん中2つの平均になります。

📘 平均値と中央値の使い分け

この2つは似ていますが、使うべき場面が違います。外れ値(極端な値)があるかどうかで選びます。

コード:外れ値がある場合の比較

import numpy as np

# 外れ値がないデータ
normal_data = np.array([10, 20, 30, 40, 50])
print("【外れ値なし】")
print(f"データ: {normal_data}")
print(f"平均: {np.mean(normal_data)}")
print(f"中央値: {np.median(normal_data)}")

# 外れ値があるデータ
outlier_data = np.array([10, 20, 30, 40, 1000])
print("\n【外れ値あり(1000)】")
print(f"データ: {outlier_data}")
print(f"平均: {np.mean(outlier_data)}")
print(f"中央値: {np.median(outlier_data)}")

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

実行結果

【外れ値なし】
データ: [10 20 30 40 50]
平均: 30.0
中央値: 30.0

【外れ値あり(1000)】
データ: [  10   20   30   40 1000]
平均: 220.0
中央値: 30.0

📌 平均と中央値の使い分け

統計量 特徴 使う場面
平均値 外れ値の影響を受けやすい データが均等に分布している時
中央値 外れ値の影響を受けにくい 年収など、外れ値がある時

📘 標準偏差を計算 – std()

std()(スタンダード・デビエーション)は、データのばらつきを表す数値です。

📝 書き方:標準偏差の計算

np.std(配列)

配列.std()

標準偏差が小さい → データが平均の近くに集中

標準偏差が大きい → データが広く散らばっている

コード:標準偏差を比較する

import numpy as np

# ばらつきが小さいデータ(50付近に集中)
data1 = np.array([48, 49, 50, 51, 52])

# ばらつきが大きいデータ(広く散らばっている)
data2 = np.array([10, 30, 50, 70, 90])

print("【ばらつき小】")
print(f"データ: {data1}")
print(f"平均: {np.mean(data1)}")
print(f"標準偏差: {np.std(data1):.2f}")

print("\n【ばらつき大】")
print(f"データ: {data2}")
print(f"平均: {np.mean(data2)}")
print(f"標準偏差: {np.std(data2):.2f}")

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

実行結果

【ばらつき小】
データ: [48 49 50 51 52]
平均: 50.0
標準偏差: 1.41

【ばらつき大】
データ: [10 30 50 70 90]
平均: 50.0
標準偏差: 28.28

💡 標準偏差の読み方

どちらも平均は50ですが:

・data1の標準偏差は1.41 → 平均±1.41の範囲にほぼ収まる

・data2の標準偏差は28.28 → 平均±28.28と広く散らばっている

テストで言えば、data1は「みんな同じくらいの点数」、data2は「点数の差が大きい」クラスです。

📊 2. 最大値・最小値

🔰 最大値と最小値を見つける

np.max()np.min()で、配列の中の最大・最小値を見つけられます。

コード:最大値と最小値を求める

import numpy as np

# 1週間の気温データ
temperatures = np.array([18.5, 21.2, 19.8, 22.5, 20.1, 17.3, 23.8])

print(f"気温データ: {temperatures}")
print()
print(f"最高気温: {np.max(temperatures)}℃")
print(f"最低気温: {np.min(temperatures)}℃")
print(f"気温の範囲: {np.max(temperatures) - np.min(temperatures)}℃")

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

実行結果

気温データ: [18.5 21.2 19.8 22.5 20.1 17.3 23.8]

最高気温: 23.8℃
最低気温: 17.3℃
気温の範囲: 6.5℃

📘 最大値・最小値の位置を見つける

「最高点は何点?」だけでなく「最高点は何番目?」を知りたいときは、argmax()argmin()を使います。

📝 書き方:位置(インデックス)を取得

np.argmax(配列) → 最大値のインデックス

np.argmin(配列) → 最小値のインデックス

arg = argument(引数)の略。「どこにあるか」を返します。

コード:最大・最小の位置を特定

import numpy as np

# 曜日別の売上データ(万円)
sales = np.array([120, 135, 150, 145, 160, 175, 180])
days = ['月', '火', '水', '木', '金', '土', '日']

print(f"売上: {sales}")

# 最大値のインデックスを取得
max_idx = np.argmax(sales)
print(f"\n最高売上: {days[max_idx]}曜日 {sales[max_idx]}万円")

# 最小値のインデックスを取得
min_idx = np.argmin(sales)
print(f"最低売上: {days[min_idx]}曜日 {sales[min_idx]}万円")

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

実行結果

売上: [120 135 150 145 160 175 180]

最高売上: 日曜日 180万円
最低売上: 月曜日 120万円

💡 コードの解説

np.argmax(sales)

・最大値180があるインデックス6を返す

days[max_idx]

・days[6]で「日」を取得

sales[max_idx]

・sales[6]で180を取得

📘 2次元配列での最大・最小(axis指定)

2次元配列では、行ごとまたは列ごとに計算することができます。

📌 axisパラメータの意味

axis 方向 結果
指定なし 全体 1つの値
axis=0 縦方向(列ごと) 各列の結果
axis=1 横方向(行ごと) 各行の結果

コード:2次元配列でaxisを使う

import numpy as np

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

print("点数データ:")
print(scores)

# 全体の最高点・最低点
print(f"\n全体の最高点: {np.max(scores)}")
print(f"全体の最低点: {np.min(scores)}")

# 各生徒の最高点(axis=1: 行ごと)
print(f"\n各生徒の最高点: {np.max(scores, axis=1)}")

# 各科目の最高点(axis=0: 列ごと)
print(f"各科目の最高点: {np.max(scores, axis=0)}")

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

実行結果

点数データ:
[[85 90 78]
 [92 88 95]
 [78 85 82]]

全体の最高点: 95
全体の最低点: 78

各生徒の最高点: [90 95 85]
各科目の最高点: [92 90 95]

💡 axisの覚え方

axis=0: 0番目の次元(行)を「潰す」→ 列ごとの計算

axis=1: 1番目の次元(列)を「潰す」→ 行ごとの計算

混乱したら、実際に試して結果を確認するのが一番です!

➕ 3. 合計と累積和

🔰 合計を計算 – sum()

np.sum()で、配列の全要素の合計を計算できます。

コード:合計を計算する

import numpy as np

# 1週間の売上(万円)
sales = np.array([120, 135, 150, 145, 160, 175, 180])

print(f"1週間の売上: {sales}")
print(f"合計売上: {np.sum(sales)}万円")
print(f"平均売上: {np.mean(sales):.1f}万円")

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

実行結果

1週間の売上: [120 135 150 145 160 175 180]
合計売上: 1065万円
平均売上: 152.1万円

📘 2次元配列の合計(axis指定)

コード:行ごと・列ごとの合計

import numpy as np

# 3店舗×5日間の売上(千円)
sales = np.array([
    [120, 135, 150, 145, 160],  # 店舗A
    [110, 125, 140, 138, 155],  # 店舗B
    [115, 130, 145, 142, 158]   # 店舗C
])

print("売上データ(店舗×日):")
print(sales)

# 各店舗の合計(axis=1: 行ごと)
store_total = np.sum(sales, axis=1)
print(f"\n各店舗の合計: {store_total}")

# 各日の合計(axis=0: 列ごと)
daily_total = np.sum(sales, axis=0)
print(f"各日の合計: {daily_total}")

# 全体の合計
print(f"全体の合計: {np.sum(sales)}千円")

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

実行結果

売上データ(店舗×日):
[[120 135 150 145 160]
 [110 125 140 138 155]
 [115 130 145 142 158]]

各店舗の合計: [710 668 690]
各日の合計: [345 390 435 425 473]
全体の合計: 2068千円

📘 累積和を計算 – cumsum()

cumsum()(キュームラティブ・サム)は、累積和(だんだん足していった値)を計算します。「今までの合計」を知りたいときに使います。

📝 書き方:累積和の計算

np.cumsum(配列)

cumulative(累積の)+ sum(合計)= cumsum

各位置で「それまでの合計」を返します。

コード:累積和を計算する

import numpy as np

# 月別売上(万円)
monthly_sales = np.array([120, 135, 150, 145, 160, 175])
months = ['1月', '2月', '3月', '4月', '5月', '6月']

# 累積売上を計算
cumulative = np.cumsum(monthly_sales)

print("月別売上と累積売上:")
for month, sales, cum in zip(months, monthly_sales, cumulative):
    print(f"  {month}: {sales}万円(累積: {cum}万円)")

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

実行結果

月別売上と累積売上:
  1月: 120万円(累積: 120万円)
  2月: 135万円(累積: 255万円)
  3月: 150万円(累積: 405万円)
  4月: 145万円(累積: 550万円)
  5月: 160万円(累積: 710万円)
  6月: 175万円(累積: 885万円)

💡 累積和の計算の流れ

元のデータ: [120, 135, 150, 145, 160, 175]

累積和: [120, 120+135=255, 255+150=405, 405+145=550, …]

使い道:累積売上、累積来客数、累積貯金額など

📊 4. パーセンタイルと四分位数

🔰 パーセンタイルとは?

パーセンタイルは、データを小さい順に並べた時の「〇%の位置の値」です。テストの偏差値や、身長・体重の成長曲線などで使われます。

📝 書き方:パーセンタイルの計算

np.percentile(配列, パーセント値)

例:np.percentile(data, 25) → 下から25%の位置の値

コード:パーセンタイルを計算する

import numpy as np

# テストの点数(小さい順に並んでいる)
scores = np.array([65, 72, 78, 82, 85, 88, 90, 92, 95, 98])

print(f"点数: {scores}")
print()

# 各パーセンタイルを計算
p25 = np.percentile(scores, 25)
p50 = np.percentile(scores, 50)
p75 = np.percentile(scores, 75)

print(f"25パーセンタイル: {p25}点")
print(f"50パーセンタイル(中央値): {p50}点")
print(f"75パーセンタイル: {p75}点")

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

実行結果

点数: [65 72 78 82 85 88 90 92 95 98]

25パーセンタイル: 79.25点
50パーセンタイル(中央値): 86.5点
75パーセンタイル: 91.5点

📌 パーセンタイルの意味

パーセンタイル 意味 別名
25 下から25%の位置 第1四分位数(Q1)
50 下から50%の位置 中央値(Q2)
75 下から75%の位置 第3四分位数(Q3)

📘 四分位数と四分位範囲(IQR)

四分位数を使ってIQR(四分位範囲)を計算できます。IQRはデータのばらつきを表す指標です。

コード:四分位数とIQRを計算

import numpy as np

data = np.array([12, 15, 18, 20, 22, 25, 28, 30, 35, 40, 45, 50])

# 四分位数を計算
q1 = np.percentile(data, 25)  # 第1四分位数
q2 = np.percentile(data, 50)  # 第2四分位数(中央値)
q3 = np.percentile(data, 75)  # 第3四分位数

# 四分位範囲(IQR)を計算
iqr = q3 - q1

print(f"データ: {data}")
print()
print(f"第1四分位数(Q1): {q1}")
print(f"第2四分位数(Q2、中央値): {q2}")
print(f"第3四分位数(Q3): {q3}")
print(f"四分位範囲(IQR = Q3 - Q1): {iqr}")

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

実行結果

データ: [12 15 18 20 22 25 28 30 35 40 45 50]

第1四分位数(Q1): 19.25
第2四分位数(Q2、中央値): 26.5
第3四分位数(Q3): 38.75
四分位範囲(IQR = Q3 - Q1): 19.5

💡 IQRの意味

IQR(四分位範囲)は「真ん中50%のデータが収まる範囲」を表します。

・IQRが小さい → データが中央に集まっている

・IQRが大きい → データが広く散らばっている

標準偏差と違い、外れ値の影響を受けにくいのが特徴です。

📘 複数のパーセンタイルを一度に計算

コード:複数のパーセンタイルを一度に取得

import numpy as np

scores = np.array([55, 62, 68, 72, 75, 78, 82, 85, 88, 90, 92, 95, 98])

# 複数のパーセンタイルをリストで指定
percentiles = np.percentile(scores, [10, 25, 50, 75, 90])

print(f"点数: {scores}")
print()
print(f"10パーセンタイル: {percentiles[0]}点")
print(f"25パーセンタイル: {percentiles[1]}点")
print(f"50パーセンタイル(中央値): {percentiles[2]}点")
print(f"75パーセンタイル: {percentiles[3]}点")
print(f"90パーセンタイル: {percentiles[4]}点")

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

実行結果

点数: [55 62 68 72 75 78 82 85 88 90 92 95 98]

10パーセンタイル: 63.2点
25パーセンタイル: 72.0点
50パーセンタイル(中央値): 82.0点
75パーセンタイル: 90.0点
90パーセンタイル: 94.0点

🔢 5. その他の便利な統計関数

📘 分散を計算 – var()

var()(バリアンス)分散を計算します。標準偏差の2乗です。

コード:分散と標準偏差の関係

import numpy as np

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

print(f"データ: {data}")
print(f"平均: {np.mean(data)}")
print(f"分散: {np.var(data)}")
print(f"標準偏差: {np.std(data)}")
print()
print(f"確認: 標準偏差の2乗 = {np.std(data) ** 2}")

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

実行結果

データ: [10 20 30 40 50]
平均: 30.0
分散: 200.0
標準偏差: 14.142135623730951

確認: 標準偏差の2乗 = 200.0

📘 条件を満たす要素をカウント – count_nonzero()

count_nonzero()は、条件を満たす要素の数を数えます。

コード:条件を満たす要素を数える

import numpy as np

# テストの点数
scores = np.array([95, 72, 88, 91, 65, 78, 85])

# 80点以上の人数をカウント
passed = np.count_nonzero(scores >= 80)
total = len(scores)

print(f"点数: {scores}")
print()
print(f"合格者(80点以上): {passed}人 / {total}人")
print(f"合格率: {passed / total * 100:.1f}%")

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

実行結果

点数: [95 72 88 91 65 78 85]

合格者(80点以上): 4人 / 7人
合格率: 57.1%

💡 コードの解説

scores >= 80

・各要素が80以上かをTrue/Falseで返す

・[True, False, True, True, False, False, True]

np.count_nonzero()

・True(= 0でない)の数を数える → 4

📘 データを標準化する

データを平均0、標準偏差1に変換することを標準化(Standardization)といいます。異なるスケールのデータを比較したいときに使います。

📝 書き方:標準化の公式

標準化した値 = (元の値 – 平均) / 標準偏差

この計算で、どんなデータも「平均0、標準偏差1」の同じスケールになります。

コード:データを標準化する

import numpy as np

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

print(f"元のデータ: {data}")
print(f"平均: {np.mean(data)}")
print(f"標準偏差: {np.std(data)}")

# 標準化
mean = np.mean(data)
std = np.std(data)
standardized = (data - mean) / std

print()
print(f"標準化後: {standardized}")
print(f"標準化後の平均: {np.mean(standardized)}")
print(f"標準化後の標準偏差: {np.std(standardized)}")

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

実行結果

元のデータ: [10 20 30 40 50]
平均: 30.0
標準偏差: 14.142135623730951

標準化後: [-1.41421356 -0.70710678  0.          0.70710678  1.41421356]
標準化後の平均: 0.0
標準化後の標準偏差: 1.0

💡 標準化はいつ使う?

異なる単位のデータを比較するときに使います。

例:身長(cm)と体重(kg)を同じスケールで比較

例:テストの点数と年収を同じ基準で評価

機械学習では、標準化は前処理の定番です!

📊 6. 実践:データの要約統計量

📘 データの基本統計量を一覧表示

実際のデータ分析では、まず基本統計量を確認します。NumPyの関数を組み合わせて、データの全体像を把握しましょう。

コード:統計サマリーを作成

import numpy as np

# テストの点数データ
scores = np.array([55, 62, 68, 72, 75, 78, 82, 85, 88, 90, 92, 95, 98])

print("📊 テスト結果の統計")
print("=" * 40)
print(f"データ数: {len(scores)}人")
print(f"合計点: {np.sum(scores)}点")
print(f"平均点: {np.mean(scores):.1f}点")
print(f"中央値: {np.median(scores):.1f}点")
print(f"最高点: {np.max(scores)}点")
print(f"最低点: {np.min(scores)}点")
print(f"範囲: {np.max(scores) - np.min(scores)}点")
print(f"標準偏差: {np.std(scores):.2f}点")
print()
print(f"第1四分位数(Q1): {np.percentile(scores, 25):.1f}点")
print(f"第3四分位数(Q3): {np.percentile(scores, 75):.1f}点")
iqr = np.percentile(scores, 75) - np.percentile(scores, 25)
print(f"四分位範囲(IQR): {iqr:.1f}点")

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

実行結果

📊 テスト結果の統計
========================================
データ数: 13人
合計点: 1040点
平均点: 80.0点
中央値: 82.0点
最高点: 98点
最低点: 55点
範囲: 43点
標準偏差: 12.49点

第1四分位数(Q1): 72.0点
第3四分位数(Q3): 90.0点
四分位範囲(IQR): 18.0点

📘 複数グループの比較

コード:2つのクラスを比較

import numpy as np

# クラスAとクラスBの点数
class_a = np.array([85, 90, 78, 92, 88, 95, 82, 87, 91, 89])
class_b = np.array([72, 68, 75, 70, 78, 74, 76, 69, 73, 71])

print("クラスA vs クラスB の比較")
print("=" * 50)

# 比較表示
print(f"{'統計量':<12} {'クラスA':>10} {'クラスB':>10}")
print("-" * 50)
print(f"{'人数':<12} {len(class_a):>10} {len(class_b):>10}")
print(f"{'平均点':<12} {np.mean(class_a):>10.1f} {np.mean(class_b):>10.1f}")
print(f"{'中央値':<12} {np.median(class_a):>10.1f} {np.median(class_b):>10.1f}")
print(f"{'最高点':<12} {np.max(class_a):>10} {np.max(class_b):>10}")
print(f"{'最低点':<12} {np.min(class_a):>10} {np.min(class_b):>10}")
print(f"{'標準偏差':<12} {np.std(class_a):>10.2f} {np.std(class_b):>10.2f}")

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

実行結果

クラスA vs クラスB の比較
==================================================
統計量           クラスA     クラスB
--------------------------------------------------
人数                  10         10
平均点              88.7       72.6
中央値              88.5       72.5
最高点                95         78
最低点                78         68
標準偏差            4.64       3.06

💡 この比較から分かること

・クラスAの方が平均・中央値ともに高い

・クラスAの標準偏差は4.64、クラスBは3.06

 → クラスBの方がばらつきが小さい(点数が揃っている)

・両クラスとも平均と中央値がほぼ同じ → 外れ値が少ない

📝 練習問題

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

問題1:基本的な統計量の計算(初級)

📋 問題

以下の配列の平均、中央値、最大値、最小値を計算してください。

data = [45, 52, 61, 48, 55, 58, 50, 47, 53, 49]

解答例を見る

コード

import numpy as np

data = np.array([45, 52, 61, 48, 55, 58, 50, 47, 53, 49])

print(f"データ: {data}")
print()
print(f"平均: {np.mean(data)}")
print(f"中央値: {np.median(data)}")
print(f"最大値: {np.max(data)}")
print(f"最小値: {np.min(data)}")

実行結果

データ: [45 52 61 48 55 58 50 47 53 49]

平均: 51.8
中央値: 51.0
最大値: 61
最小値: 45

問題2:累積和の計算(初級)

📋 問題

月別の貯金額 [30000, 25000, 35000, 40000, 30000] を配列にして、累積貯金額を計算してください。

解答例を見る

コード

import numpy as np

monthly_savings = np.array([30000, 25000, 35000, 40000, 30000])
cumulative = np.cumsum(monthly_savings)

print(f"月別貯金額: {monthly_savings}")
print(f"累積貯金額: {cumulative}")
print()
for i, (monthly, total) in enumerate(zip(monthly_savings, cumulative), 1):
    print(f"{i}ヶ月目: {monthly:,}円(累積: {total:,}円)")

実行結果

月別貯金額: [30000 25000 35000 40000 30000]
累積貯金額: [ 30000  55000  90000 130000 160000]

1ヶ月目: 30,000円(累積: 30,000円)
2ヶ月目: 25,000円(累積: 55,000円)
3ヶ月目: 35,000円(累積: 90,000円)
4ヶ月目: 40,000円(累積: 130,000円)
5ヶ月目: 30,000円(累積: 160,000円)

問題3:2次元配列での統計計算(中級)

📋 問題

以下の3人×3科目の点数データがあります。各生徒の平均点と、各科目の平均点を計算してください。

scores = [[80, 75, 90], [85, 92, 88], [78, 82, 85]]

解答例を見る

コード

import numpy as np

scores = np.array([
    [80, 75, 90],  # 太郎
    [85, 92, 88],  # 花子
    [78, 82, 85]   # 次郎
])

print("点数データ:")
print(scores)

# 各生徒の平均(axis=1: 行ごと)
student_avg = np.mean(scores, axis=1)
print("\n各生徒の平均点:")
students = ['太郎', '花子', '次郎']
for name, avg in zip(students, student_avg):
    print(f"  {name}: {avg:.1f}点")

# 各科目の平均(axis=0: 列ごと)
subject_avg = np.mean(scores, axis=0)
print("\n各科目の平均点:")
subjects = ['国語', '数学', '英語']
for subject, avg in zip(subjects, subject_avg):
    print(f"  {subject}: {avg:.1f}点")

実行結果

点数データ:
[[80 75 90]
 [85 92 88]
 [78 82 85]]

各生徒の平均点:
  太郎: 81.7点
  花子: 88.3点
  次郎: 81.7点

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

問題4:四分位数の計算(中級)

📋 問題

以下のデータの第1四分位数、中央値、第3四分位数、四分位範囲(IQR)を計算してください。

data = [12, 15, 18, 20, 22, 25, 28, 30, 32, 35, 38, 40, 45, 50, 55]

解答例を見る

コード

import numpy as np

data = np.array([12, 15, 18, 20, 22, 25, 28, 30, 32, 35, 38, 40, 45, 50, 55])

q1 = np.percentile(data, 25)
q2 = np.percentile(data, 50)
q3 = np.percentile(data, 75)
iqr = q3 - q1

print(f"データ: {data}")
print()
print(f"第1四分位数(Q1): {q1}")
print(f"中央値(Q2): {q2}")
print(f"第3四分位数(Q3): {q3}")
print(f"四分位範囲(IQR): {iqr}")

実行結果

データ: [12 15 18 20 22 25 28 30 32 35 38 40 45 50 55]

第1四分位数(Q1): 21.0
中央値(Q2): 30.0
第3四分位数(Q3): 41.25
四分位範囲(IQR): 20.25

問題5:条件付き統計(上級)

📋 問題

以下の点数データから、80点以上の点数だけを抽出して、その平均、最大値、最小値、個数を計算してください。

scores = [95, 72, 88, 91, 65, 78, 85, 92, 70, 87, 83, 76, 90]

解答例を見る

コード

import numpy as np

scores = np.array([95, 72, 88, 91, 65, 78, 85, 92, 70, 87, 83, 76, 90])

# 80点以上を抽出
high_scores = scores[scores >= 80]

print(f"全体の点数: {scores}")
print(f"80点以上: {high_scores}")
print()
print(f"80点以上の統計:")
print(f"  個数: {len(high_scores)}人")
print(f"  平均: {np.mean(high_scores):.1f}点")
print(f"  最高: {np.max(high_scores)}点")
print(f"  最低: {np.min(high_scores)}点")
print(f"  割合: {len(high_scores) / len(scores) * 100:.1f}%")

実行結果

全体の点数: [95 72 88 91 65 78 85 92 70 87 83 76 90]
80点以上: [95 88 91 85 92 87 83 90]

80点以上の統計:
  個数: 8人
  平均: 88.9点
  最高: 95点
  最低: 83点
  割合: 61.5%

問題6:データの標準化(上級)

📋 問題

以下のデータを標準化(平均0、標準偏差1に変換)してください。標準化後の平均と標準偏差も確認してください。

data = [20, 25, 30, 35, 40, 45, 50]

解答例を見る

コード

import numpy as np

data = np.array([20, 25, 30, 35, 40, 45, 50])

print(f"元のデータ: {data}")
print(f"元の平均: {np.mean(data)}")
print(f"元の標準偏差: {np.std(data)}")

# 標準化: (値 - 平均) / 標準偏差
mean = np.mean(data)
std = np.std(data)
standardized = (data - mean) / std

print()
print(f"標準化後: {standardized}")
print(f"標準化後の平均: {np.mean(standardized):.10f}")
print(f"標準化後の標準偏差: {np.std(standardized)}")

実行結果

元のデータ: [20 25 30 35 40 45 50]
元の平均: 35.0
元の標準偏差: 10.0

標準化後: [-1.5 -1.  -0.5  0.   0.5  1.   1.5]
標準化後の平均: 0.0000000000
標準化後の標準偏差: 1.0

🎯 このステップのまとめ

✅ 学んだこと

np.mean()で平均値を計算できる

np.median()で中央値を計算できる

np.std()で標準偏差を計算できる

np.max()/np.min()で最大値・最小値を見つけられる

np.argmax()/np.argmin()で位置を見つけられる

np.sum()で合計、np.cumsum()で累積和を計算できる

np.percentile()でパーセンタイルを計算できる

axisパラメータで行ごと・列ごとの計算ができる

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

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

□ 基本的な統計量(平均、中央値、標準偏差)を計算できる

□ 2次元配列でaxisを使って計算できる

□ 累積和の使い方がわかる

□ パーセンタイルと四分位数を計算できる

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

❓ よくある質問

Q1: 平均と中央値はどう使い分けますか?

A: 外れ値がない場合は平均外れ値がある場合は中央値を使います。例えば、年収データなど極端に大きい値がある場合は、中央値の方が実態を表します。

Q2: 標準偏差と分散の違いは?

A: 標準偏差は分散の平方根です。標準偏差は元のデータと同じ単位なので解釈しやすいです。通常は標準偏差を使います。

Q3: axisの0と1はどう覚えればいいですか?

A: axis=0縦方向(列ごと)axis=1横方向(行ごと)です。「axis=0は行を潰す」「axis=1は列を潰す」と覚えると良いでしょう。

Q4: パーセンタイルは何に使いますか?

A: データの分布を理解するために使います。「上位10%」「下位25%」など、相対的な位置を知りたい時に便利です。

Q5: 累積和はどんな時に使いますか?

A: 「今までの合計」を知りたい時に使います。月別売上の累積、累積来客数、累積貯金額など、時系列データで「積み上げ」を見たい場合に便利です。

📝

学習メモ

Pythonデータ分析入門 - Step 20

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