2

ジェネレーターを使用する場合、1回のパスでのみアイテムを引き出すことができます。別の方法は、ジェネレーターをリストにロードして複数のパスを実行することですが、これにはパフォーマンスとメモリ割り当てへの影響が伴います。

ジェネレータから次のメトリックをシングルパスで計算するためのより良い方法を誰かが考えることができますか?理想的には、コードは、カウント、合計、平均、sd、最大、最小、および考えられるその他の統計を計算します。

アップデート

この要点の最初の恐ろしいコード。ここで要点を参照してください:https ://gist.github.com/3038746

ここで@larsmansからのすばらしい提案を使用することが、私が行った最終的な解決策です。名前付きタプルを使用すると、非常に役立ちました。

import random
from math import sqrt
from collections import namedtuple

def stat(gen):
    """Returns the namedtuple Stat as below."""
    Stat = namedtuple('Stat', 'total, sum, avg, sd, max, min')
    it = iter(gen)

    x0 = next(it)
    mx = mn = s = x0
    s2 = x0*x0
    n = 1

    for x in it:
        mx = max(mx, x)
        mn = min(mn, x)
        s += x
        s2 += x*x
        n += 1

    return Stat(n, s, s/n, sqrt(s2/n - s*s/n/n), mx, mn)

def random_int_list(size=100, start=0, end=1000):
    return (random.randrange(start,end,1) for x in xrange(size))

if __name__ == '__main__':
    r = stat(random_int_list())
    print r  #Stat(total=100, sum=56295, avg=562, sd=294.82537204250247, max=994, min=10)
4

1 に答える 1

7
def statistics(it):
    """Returns number of elements, sum, max, min"""

    it = iter(it)

    x0 = next(it)
    maximum = minimum = total = x0
    n = 1

    for x in it:
        maximum = max(maximum, x)
        minimum = min(minimum, x)
        total += x
        n += 1

    return n, total, maximum, minimum

必要に応じて他の統計を追加します。namedtuple計算する統計の数が大きくなる場合は、を使用することを検討してください。

本当に凝ったものにしたい場合は、統計コレクターのOO階層を構築できます(テストされていません)。

class Summer(object):
    def __init__(self, x0=0):
        self.value = x0

    def add(self, x):
        self.value += x

class SquareSummer(Summer):
    def add(self, x):
        super(SquareSummer, self).add(x ** 2)

class Maxer(object):
    def __init__(self, x0):
        self.value = x0

    def add(self, x):
        self.value = max(self.value, x)

# example usage: collect([Maxer, Summer], iterable)
def collect(collectors, it):
    it = iter(it)

    x0 = next(it)
    collectors = [c(x0) for c in collectors]

    for x in it:
        for c in collectors:
            c.add(x)

    return [c.value for c in collectors]
于 2012-07-03T09:40:45.753 に答える