Python

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

こんにちは!土門大貴(daikidomon)です。

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© スタートアップIT企業社長のブログ , 2020 All Rights Reserved.