Python プログラミング

[Python] 平均値・中央値・最頻値を取得

こんにちは!シミダイ(@shimidai2100)です。

Pythonで平均値・中央値・最頻値を取得するコードを紹介します。

自分で「アルゴリズムをするパターン」と「statisticsライブラリ」の2つのパターンで作成しましたの違いを確認してみてください。


平均値・中央値・最頻値を取得

↓がソースになります。

import math
import collections

if  __name__ == '__main__':
    # CSVファイルを入力
    data = []
    fname = input("Please input csv file : ")

    with open(fname, mode='r') as f:
        readArray = f.readline().split(',')
        data = list(map(int, readArray))

    # 平均値を計算
    sum = sum(data)
    count = len(data)
    average = sum / len(data)

    # 中央値を計算
    dataLength = len(data)
    sortedData = sorted(data)

    # 偶数の場合
    if dataLength % 2 == 0:
        medianLowCount = int(dataLength / 2) - 1  # 中央値が左側の添字
        medianHighCount = int(dataLength / 2 + 1) - 1 # 中央値が右側の添字
        medianLow = sortedData[medianLowCount] # 中央値が左側の数字
        medianHigh = sortedData[medianHighCount] # 中央値が右側の数字
        median = (medianLow + medianHigh) / 2
    # 奇数の場合
    else:
        # データ長 / 2 で切り上げた数がリストの中央値
        medianCount = math.floor(dataLength / 2)
        median = sortedData[medianCount]

    # 最頻値を計算
    # 最頻値が複数ある場合も考慮する
    # 出現回数が最大の数はmodeのリストに追加する
    counter = collections.Counter(data)
    freqCheck = counter.most_common()


    mode = [freqCheck[0][0]] # 最頻値
    maxCount = freqCheck[0][1] # 最頻値の出現回数

    # 最頻値の出現回数が同じ数字は最頻値とする
    count = 1
    while maxCount == freqCheck[count][1]:
        mode.append(freqCheck[count][0])
        count = count + 1

    # 元データリスト/ソート後のデータリスト/データリスト長/平均値/中央値/最頻値を出力
    print('DataList   = ' + str(data))
    print('SortedData = ' + str(sortedData))
    print('DataLength = ' + str(dataLength))
    print('Average    = ' + str(average))
    print('Median     = ' + str(median))
    print('Mode       = ' + str(mode))

また今回読み込ませるファイルは↓になります。

20,40,29,55,10,38,29,69,73,19,20,63,30,31,77,99,80,87,100,8

コードの解説

今回は「collections」で最頻値を取得するためimportさせます。

デフォルトコンポーネントではないので、入れていない人は「pip」でインストールしましょう。

頑張れば数え上げることができますが「collections」が一般的なようです。

withを使用してファイルをオープンしているため、close忘れがありません。

開いたファイルのcsv区切りのデータを読み込んだ後、map()を使って整数値にしている点に注意してください。

import math
import statistics
import collections

if  __name__ == '__main__':
    # CSVファイルを入力
    data = []
    fname = input("Please input csv file : ")

    with open(fname, mode='r') as f:
        readArray = f.readline().split(',')
        data = list(map(int, readArray))

平均値は(データの合計 / データ長)で取得します。

    # 平均値を計算
    sum = sum(data)
    count = len(data)
    average = sum / len(data)

中央値の計算はデータ長が偶数と奇数の場合で処理が変わるためif文で制御しています。

    # 中央値を計算
    dataLength = len(data)
    sortedData = sorted(data)

    # 偶数の場合
    if dataLength % 2 == 0:
        medianLowCount = int(dataLength / 2) - 1  # 中央値が左側の添字
        medianHighCount = int(dataLength / 2 + 1) - 1 # 中央値が右側の添字
        medianLow = sortedData[medianLowCount] # 中央値が左側の数字
        medianHigh = sortedData[medianHighCount] # 中央値が右側の数字
        median = (medianLow + medianHigh) / 2
    # 奇数の場合
    else:
        # データ長 / 2 で切り上げた数がリストの中央値
        medianCount = math.floor(dataLength / 2)
        median = sortedData[medianCount]

最頻値は複数ある場合の確認も行っています。

# 最頻値を計算
# 最頻値が複数ある場合も考慮する
# 出現回数が最大の数はmodeのリストに追加する
counter = collections.Counter(data)
freqCheck = counter.most_common()

mode = [freqCheck[0][0]] # 最頻値
maxCount = freqCheck[0][1] # 最頻値の出現回数

# 最頻値の出現回数が同じ数字は最頻値とする
count = 1
while maxCount == freqCheck[count][1]:
    mode.append(freqCheck[count][0])
    count = count + 1

 

statisticsライブラリを利用する場合

statisticsライブラリを利用すると更にコード簡素化することができます。

import math
import statistics

if  __name__ == '__main__':
    # CSVファイルを入力
    data = []
    fname = input("Please input csv file : ")

    with open(fname, mode='r') as f:
        readArray = f.readline().split(',')
        data = list(map(int, readArray))

    # データリスト長
    dataLength = len(data)

    # データをソートする
    sortedData = sorted(data)

    # 平均値を計算
    average = statistics.mean(data)

    # 中央値を計算
    median = statistics.median(data)

    # 最頻値を計算
    mode = statistics.mode(data)

    # 元データリスト/ソート後のデータリスト/データリスト長/平均値/中央値/最頻値を出力
    print('DataList   = ' + str(data))
    print('SortedData = ' + str(sortedData))
    print('DataLength = ' + str(dataLength))
    print('Average    = ' + str(average))
    print('Median     = ' + str(median))
    print('Mode       = ' + str(mode))

かなりすっきり書くことが出来ます。

ただし最頻値が複数存在する場合「statistics.StatisticsError: no unique mode; found 2 equally common values」が出力されるため注意して下さい。

 

関連記事

-Python, プログラミング

Copyright© shimidai2100 , 2020 All Rights Reserved.