2016年8月24日水曜日

開発環境

Pythonからはじめる数学入門 (Amit Saha (著)、黒川 利明 (翻訳)、オライリージャパン)の3章(データを統計量で記述する)、3.9(プログラミングチャレンジ)、問題3-4(百分位を求める)をJavaScript(とstatistics.js)で取り組んでみる。

問題3-4(百分位を求める)

CSVファイル(WWDI | Population, total - Japan)

コード(Emacs)

HTML5

<div id="output0"></div>

<input id="nums_data" type="file">

<script src="statistics.js"></script>
<script src="sample4.js"></script>

JavaScript

(function () {
    'use strict';
    Array.prototype.sum = function () {
        var s = 0;

        this.forEach(function (num) {
            s += num;
        });
        return s;
    };
    Array.prototype.mean = function () {
        var s = this.sum(),
            n = this.length;

        return s / n;
    };
    Array.prototype.median = function () {
        var numbers = this.slice(),
            len = numbers.length,
            i1,
            i2,
            median;

        numbers.sort(function (x, y) {
            return x - y;
        });
        if (len % 2 === 0) {
            i1 = len / 2 - 1;
            i2 = i1 + 1;
            median = (numbers[i1] + numbers[i2]) / 2;
        } else {
            i1 = (len + 1) / 2 - 1;
            median = numbers[i1];
        }
        return median;
    };
    Array.prototype.modes = function () {
        var obj = {},
            count,
            num,
            max = 0,
            modes = [];

        this.forEach(function (num) {
            if (obj[num] === undefined) {
                obj[num] = 1;
                if (max === 0) {
                    max = 1;
                }
            } else {
                count = obj[num] + 1;
                obj[num] = count;
                if (count > max) {
                    max = count;
                }
            }
        });
        for (num in obj) {
            if (obj[num] === max) {
                modes.push(parseInt(num, 10));
            }
        }
        return modes;
    };
    Array.prototype.differences = function () {
        var mean = this.mean(),
            diff;

        diff = this.map(function (num) {
            return num - mean;
        });
        return diff;
    };
    Array.prototype.variance = function () {
        var diff = this.differences(),
            squared_diff,
            len = this.length;

        squared_diff = diff.map(function (x) {
            return Math.pow(x, 2);
        });
        return squared_diff.sum() / len;
    };
    Array.prototype.standard_deviation = function () {
        var variance = this.variance(),
            std_deviation = Math.sqrt(variance);

        return std_deviation;
    };
    Array.prototype.percentile = function (p) {
        var numbers = this.slice(),
            n = numbers.length,
            i = n * p / 100 + 0.5,
            k = Math.floor(i),
            f,
            result;

        numbers.sort(function (x, y) {
            return x - y;
        });
        if (k === i) {
            result = numbers[i];
        } else {
            f = i - k;
            result = (1 - f) * numbers[k - 1] + f * numbers[k]
        }
        return result;
    };
}(this));
(function () {
    'use strict';
    var div_output = document.querySelector('#output0'),
        input_nums_data = document.querySelector('#nums_data'),
        range,
        getNumbers,
        display;

    range = function (start, end, step) {
        var nums = [],
            i;

        for (i = start; i < end; i += step) {
            nums.push(i);
        }
        return nums;
    };

    getNumbers = function () {
        var file = input_nums_data.files[0],
            reader,
            numbers = [],
            i,
            max = 100;

        if (file === undefined) {
            for (i = 0; i < max; i += 1) {
                numbers.push(Math.floor(Math.random() * 100) + 1);
            }
            display(numbers);
        } else {
            reader = new FileReader();
            reader.readAsText(file);
            reader.onload = function () {
                var text = reader.result;

                numbers = text.split('\n')
                    .map(function (x) {
                        return x.trim();
                    })
                    .filter(function (x) {
                        return x !== '';
                    })
                    .map(function (x) {
                        return parseFloat(x);
                    });
                display(numbers);
            };
            reader.onerror = function (error) {
                div_output.innerText = error;
            };
        }
    };

    display = function (numbers) {
        var numbers0 = numbers.slice(),
            percentiles = range(5, 100, 5),
            output = '',
            nl = '<br>';

        numbers0.sort(function (x, y) {
            return x - y;
        });
        output +=
            '数のリスト: ' + numbers.join(',') + nl +
            '昇順     : ' + numbers0.join(',') + nl;

        percentiles.forEach(function (p) {
            output += p + '百分位: ' + numbers.percentile(p) + nl;
        });
        div_output.innerHTML = output;
    };

    input_nums_data.onchange = getNumbers;

    getNumbers();
}());
数のリスト: 35,31,13,37,77,63,38,64,53,76,94,79,57,15,88,76,5,21,24,50,73,1,82,16,54,77,80,86,22,93,10,14,57,77,81,40,76,15,53,39,42,59,51,51,77,3,85,50,35,84,3,3,54,92,42,20,30,11,42,20,91,86,97,100,24,43,62,22,64,45,95,17,19,46,80,22,69,98,76,95,16,81,69,25,8,6,20,97,68,14,23,5,61,64,84,12,88,53,94,68
昇順 : 1,3,3,3,5,5,6,8,10,11,12,13,14,14,15,15,16,16,17,19,20,20,20,21,22,22,22,23,24,24,25,30,31,35,35,37,38,39,40,42,42,42,43,45,46,50,50,51,51,53,53,53,54,54,57,57,59,61,62,63,64,64,64,68,68,69,69,73,76,76,76,76,77,77,77,77,79,80,80,81,81,82,84,84,85,86,86,88,88,91,92,93,94,94,95,95,97,97,98,100
5百分位: 5
10百分位: 11.5
15百分位: 15
20百分位: 19.5
25百分位: 22
30百分位: 24.5
35百分位: 36
40百分位: 42
45百分位: 48
50百分位: 53
55百分位: 57
60百分位: 63.5
65百分位: 68.5
70百分位: 76
75百分位: 77
80百分位: 81
85百分位: 85.5
90百分位: 91.5
95百分位: 95

0 コメント:

コメントを投稿