3

通常はファイルに大量のデータがあります。いくつかの量を計算したいので、この種の関数があります:

def mean(iterator):
    n = 0
    sum = 0.
    for i in iterator:
      sum += i
      n += 1
    return sum / float(n)

他にも多くの同様の機能があります(varsize、 ...)

これで、データを反復処理するイテレータができました: iter_data. 必要なすべての量を計算できます:m = mean(iter_data); v = var(iter_data)などですが、問題は、何度も反復していて、私の場合はコストがかかることです。実際、I/O は最も高価な部分です。

問題は、新しい関数を簡単に追加できるように、関数、 、 ...を分離したまま1 回だけm, v, ...反復する量を計算できるかということです。iter_data meanvar

私が必要とするのは、boost::accumulatorsに似たものです

4

4 に答える 4

2

マジックを使用itertools.teeしてジェネレーターにすることができます(マジックと言うのは、正確に素晴らしく読みやすいわけではないためです):

import itertools

def mean(iterator):
    n = 0
    sum = 0.
    for i in iterator:
         sum += i
         n += 1
         yield
    yield sum / float(n)

def multi_iterate(funcs, iter_data):
    iterators = itertools.tee(iter_data, len(funcs))
    result_iterators = [func(values) for func, values in zip(funcs, iterators)]
    for results in itertools.izip(*result_iterators):
        pass
    return results

mean_result, var_result = multi_iterate([mean, var], iter([10, 20, 30]))

print(mean_result)    # 20.0

ちなみに、meanもっと簡単な方法で書くことができます:

def mean(iterator):
    total = 0.
    for n, item in enumerate(iterator, 1):
         total += i
         yield
    yield total / n

sum組み込み関数を同じ名前で隠してしまうため、変数に名前を付けるべきではありません。

于 2013-08-21T15:16:09.800 に答える