Pythonで中央値を求める方法|初心者向け完全ガイド

python

データを分析するとき、「平均値」だけでなく「中央値」も知りたくなることがありますよね。

中央値とは

  • データを小さい順に並べたときの真ん中の値
  • 英語で「メジアン(median)」と呼ぶ
  • 極端に大きい値や小さい値に影響されにくい

この記事では、Pythonで中央値を求めるいろいろな方法を、分かりやすく説明します。

スポンサーリンク

中央値の基本的な考え方

奇数個のデータの場合

データ:[10, 20, 30, 40, 50]
並び順:10 ← 20 ← 30 ← 40 ← 50
               ↑
            真ん中
中央値:30

偶数個のデータの場合

データ:[10, 20, 30, 40]
並び順:10 ← 20 ← 30 ← 40
             ↑   ↑
           真ん中の2つ
中央値:(20 + 30) ÷ 2 = 25

方法1:Pythonの標準機能を使う(statistics)

Pythonには最初から中央値を計算する機能が入っています。

基本的な使い方

import statistics

# 奇数個のデータ
data1 = [10, 20, 30, 40, 50]
median1 = statistics.median(data1)
print(median1)  # 30

# 偶数個のデータ
data2 = [1, 2, 3, 4]
median2 = statistics.median(data2)
print(median2)  # 2.5

実際の例

import statistics

# テストの点数
scores = [85, 92, 78, 96, 88, 73, 91]
median_score = statistics.median(scores)
print(f"テストの中央値: {median_score}点")  # 88点

# 年齢データ
ages = [25, 30, 22, 35, 28, 40, 26]
median_age = statistics.median(ages)
print(f"年齢の中央値: {median_age}歳")  # 28歳

注意点

import statistics

# 空のリストはエラーになる
try:
    empty_data = []
    statistics.median(empty_data)
except statistics.StatisticsError:
    print("データが空です")

# データが1つでもOK
single_data = [100]
print(statistics.median(single_data))  # 100

方法2:NumPyを使う(大量データに最適)

NumPyは数値計算が得意なライブラリです。大量のデータを扱うときに便利です。

インストール方法

pip install numpy

基本的な使い方

import numpy as np

# リストから中央値を計算
data = [100, 200, 300, 400, 500]
median_value = np.median(data)
print(median_value)  # 300.0

# 配列から中央値を計算
array_data = np.array([1, 5, 3, 9, 7])
print(np.median(array_data))  # 5.0

2次元配列の場合

import numpy as np

# 2次元配列(行列)
matrix = np.array([[1, 2, 3],
                   [4, 5, 6],
                   [7, 8, 9]])

# 全体の中央値
print(np.median(matrix))  # 5.0

# 各行の中央値
print(np.median(matrix, axis=1))  # [2. 5. 8.]

# 各列の中央値
print(np.median(matrix, axis=0))  # [4. 5. 6.]

大量データの処理例

import numpy as np
import time

# 100万個のランダムなデータを作成
large_data = np.random.randint(1, 1000, 1000000)

# 処理時間を測定
start_time = time.time()
median_result = np.median(large_data)
end_time = time.time()

print(f"中央値: {median_result}")
print(f"処理時間: {end_time - start_time:.4f}秒")

方法3:pandasを使う(データ分析に最適)

pandasはデータ分析によく使われるライブラリです。表形式のデータを扱うのが得意です。

インストール方法

pip install pandas

基本的な使い方

import pandas as pd

# データフレーム(表)を作成
df = pd.DataFrame({
    '名前': ['田中', '佐藤', '鈴木', '高橋', '伊藤'],
    '年齢': [25, 30, 22, 35, 28],
    '年収': [400, 500, 350, 600, 450]
})

# 特定の列の中央値
print(f"年齢の中央値: {df['年齢'].median()}歳")  # 28歳
print(f"年収の中央値: {df['年収'].median()}万円")  # 450万円

# 全ての数値列の中央値
print(df.median())

欠損値がある場合

import pandas as pd
import numpy as np

# 欠損値(NaN)を含むデータ
data = pd.Series([10, 20, np.nan, 30, 40])
print(data.median())  # 25.0(NaNは自動で無視される)

# 欠損値の確認
print(data.isna().sum())  # 1個の欠損値

グループごとの中央値

import pandas as pd

# 部署別のデータ
df = pd.DataFrame({
    '部署': ['営業', '営業', '技術', '技術', '総務'],
    '年齢': [25, 30, 28, 35, 32],
    '年収': [400, 450, 500, 600, 420]
})

# 部署ごとの中央値
group_median = df.groupby('部署').median()
print(group_median)

方法4:自分で中央値を計算する

ライブラリを使わずに、自分で中央値を計算する方法も覚えておきましょう。

基本的な関数

def calculate_median(numbers):
    """中央値を計算する関数"""
    # 空のリストをチェック
    if not numbers:
        return None
    
    # データを小さい順に並べ替え
    sorted_numbers = sorted(numbers)
    n = len(sorted_numbers)
    
    # 真ん中の位置を計算
    middle = n // 2
    
    if n % 2 == 0:
        # 偶数個の場合:真ん中の2つの平均
        return (sorted_numbers[middle - 1] + sorted_numbers[middle]) / 2
    else:
        # 奇数個の場合:真ん中の値
        return sorted_numbers[middle]

# 使用例
data1 = [5, 2, 8, 1, 9]
print(f"中央値: {calculate_median(data1)}")  # 5

data2 = [3, 1, 4, 2]
print(f"中央値: {calculate_median(data2)}")  # 2.5

エラーハンドリング付きの関数

def safe_median(numbers):
    """エラーチェック付きの中央値計算"""
    # 空のチェック
    if not numbers:
        raise ValueError("データが空です")
    
    # 数値以外が含まれていないかチェック
    try:
        numeric_data = [float(x) for x in numbers]
    except (ValueError, TypeError):
        raise ValueError("数値以外のデータが含まれています")
    
    # 中央値を計算
    sorted_data = sorted(numeric_data)
    n = len(sorted_data)
    middle = n // 2
    
    if n % 2 == 0:
        return (sorted_data[middle - 1] + sorted_data[middle]) / 2
    else:
        return sorted_data[middle]

# 使用例
try:
    result = safe_median([1, 2, 3, 4, 5])
    print(f"中央値: {result}")
except ValueError as e:
    print(f"エラー: {e}")

各方法の比較

方法ライブラリ特徴おすすめ用途
statistics.median()標準簡単、追加インストール不要小規模データ、学習用
np.median()NumPy高速、大量データ対応数値計算、大量データ
df.median()pandas欠損値対応、表形式データデータ分析、CSV処理
自作関数なしカスタマイズ可能学習、特殊要件

よくある問題と解決方法

問題1:空のデータでエラーになる

import statistics

# 問題のあるコード
data = []
try:
    result = statistics.median(data)
except statistics.StatisticsError:
    print("データが空のため計算できません")

# 改善したコード
def safe_calculate_median(data):
    if len(data) == 0:
        return None
    return statistics.median(data)

問題2:文字列や None が混ざっている

import statistics

# 問題のあるデータ
mixed_data = [1, 2, '3', None, 5]

# データをクリーンアップ
clean_data = []
for item in mixed_data:
    try:
        clean_data.append(float(item))
    except (ValueError, TypeError):
        pass  # 数値に変換できないものは無視

result = statistics.median(clean_data)
print(f"中央値: {result}")

問題3:処理速度が遅い

import time
import statistics
import numpy as np

# 大量のデータを作成
large_data = list(range(1000000))

# statistics.median の時間測定
start = time.time()
result1 = statistics.median(large_data)
time1 = time.time() - start

# numpy の時間測定
start = time.time()
result2 = np.median(large_data)
time2 = time.time() - start

print(f"statistics: {time1:.4f}秒")
print(f"numpy: {time2:.4f}秒")
print(f"numpy の方が {time1/time2:.1f}倍高速")

実践的な例

例1:テストの成績分析

import pandas as pd

# テストの点数データ
scores = {
    '数学': [85, 92, 78, 96, 88, 73, 91, 87, 94, 82],
    '英語': [88, 85, 91, 89, 92, 86, 88, 90, 87, 93],
    '国語': [76, 89, 85, 91, 88, 82, 87, 85, 90, 86]
}

df = pd.DataFrame(scores)

print("各科目の中央値:")
for subject in df.columns:
    median_score = df[subject].median()
    print(f"{subject}: {median_score}点")

print(f"\n全体の中央値: {df.median().median():.1f}点")

例2:売上データの分析

import pandas as pd
import numpy as np

# 月別売上データ
sales_data = pd.DataFrame({
    '月': ['1月', '2月', '3月', '4月', '5月', '6月'],
    '売上': [120, 135, 150, 145, 160, 155]
})

# 売上の中央値
median_sales = sales_data['売上'].median()
mean_sales = sales_data['売上'].mean()

print(f"売上の中央値: {median_sales}万円")
print(f"売上の平均値: {mean_sales:.1f}万円")

# 中央値より高い月を探す
high_months = sales_data[sales_data['売上'] > median_sales]
print(f"\n中央値より高い売上の月:")
print(high_months[['月', '売上']])

まとめ

Pythonで中央値を求める方法はたくさんありますが、用途に応じて使い分けることが大切です。

初心者におすすめ

  • まずは statistics.median() から始める
  • 簡単で、追加のライブラリインストールが不要

データ分析をする場合

  • pandas の .median() を使う
  • 欠損値の処理が楽で、表形式データに最適

大量データや高速処理が必要

  • NumPy の np.median() を使う
  • 計算速度が速く、メモリ効率も良い

重要なポイント

  • 中央値は極端な値に影響されにくい
  • 平均値と合わせて見ることで、データの特徴がよく分かる
  • エラーハンドリングを忘れずに

基本コマンド一覧

# 標準ライブラリ
import statistics
statistics.median([1, 2, 3, 4, 5])

# NumPy
import numpy as np
np.median([1, 2, 3, 4, 5])

# pandas
import pandas as pd
df = pd.DataFrame({'data': [1, 2, 3, 4, 5]})
df['data'].median()

最初は基本的な方法から始めて、必要に応じて他の方法も覚えていけば、データ分析がもっと楽しくなりますよ!

コメント

タイトルとURLをコピーしました