2

オブジェクトのグループを反復処理して、最も効率的な方法でそれらの平均を見つけるにはどうすればよいですか?これは1つのループだけを使用します(おそらくNumpyのループを除く)が、もっと良い方法があるかどうか疑問に思いました。現在、私はこれを行っています:

scores = []
ratings= []
negative_scores = []
positive_scores = []

for t in text_collection:
 scores.append(t.score)
 ratings.append(t.rating)
 if t.score < 0:
    negative_scores.append(t.score)
 elif t.score > 0:
    positive_scores.append(t.score)

print "average score:", numpy.mean(scores)
print "average rating:", numpy.mean(ratings)
print "average negative score:", numpy.mean(negative_scores)
print "average positive score:", numpy.mean(positive_scores)

これを行うためのより良い方法はありますか?

4

4 に答える 4

6
import numpy as np
scores, ratings = np.array([(t.score, t.rating) for t in text_collection]).T

print 'average score: ', np.mean(scores)
print 'average rating: ', np.mean(ratings)
print 'average positive score: ', np.mean(scores[scores > 0])
print 'average negative score: ', np.mean(scores[scores < 0])

編集:

実際に負のスコアがあるかどうかを確認するには、次のようにします。

if np.count_nonzero(scores < 0):
    print 'average negative score: ', np.mean(scores[scores < 0])
于 2012-06-03T21:21:43.300 に答える
1

コレクションから取得したいアイテムごとにループしてもよろしいですか?効率はわずかに低下しますが、はるかに明確です。

avg_score = numpy.mean([t.score for t in text_collection])
avg_rating = numpy.mean([t.rating for t in text_collection])
avg_neg_score = numpy.mean([t.rating for t in text_collection if t.score < 0])
avg_pos_score = numpy.mean([t.rating for t in text_collection if t.score > 0])
于 2012-06-03T20:53:02.913 に答える
0

NumPyを利用できる場合は、それが最善の策だと思います。それはあなたが望むことを正確に行い、あなたがしていることを自己文書化する名前を持っています。

純粋なPythonソリューションが必要な場合:

def mean(seq):
    i = 0
    sum = 0.0
    for x in seq:
        sum += x
        i += 1
    if i == 0:
        raise ValueError, "cannot take mean of zero-length sequence"
    return sum / i

値を計算するジェネレータ式など、あらゆるシーケンスで機能するように作成しました。したがって、シーケンスは1回だけ実行され、独自のカウンターを保持するため、いくつあったかがわかります。あなたが確かにあなたがリストの平均を取りたいだけであると知っているならば:

def list_mean(lst):
    if len(lst) == 0:
        raise ValueError, "cannot take mean of zero-length list"
    return float(sum(lst)) / len(lst)

イテレータまたはジェネレータ式でこれを呼び出すと、len()は機能せず、TypeError例外が発生します。

于 2012-06-03T21:03:52.010 に答える
0

簡単な操作でavg_neg_scoreとavg_pos_scoreからavg_scoreを取得できます。

nneg = len(negative_scores)
npos = len(positive_scores)
avg_score = (avg_neg_score * nneg + avg_pos_score * npos) / (nneg + npos)

編集:text_collectionを反復して配列を作成している場合、これはより効率的です(手段のみが必要であると想定):

n = len(text_collection)
(npos, sumpos) = (0, 0)
(nneg, sumneg) = (0, 0)
sumrating = 0
for t in text_collection:
    sumrating += t.rating
    if t.score < 0:
        sumneg += t.score
        nneg += 1
    else:
        sumpos += t.score
        npos += 1
avg_score = (sumneg + sumpos) / n
avg_neg_score = sumneg / nneg
avg_pos_score = sumpos / npos
avg_rating = sumrating / n

edit2:修正済み:avg_neg_ratingからavg_neg_score .. ..

于 2012-06-03T21:15:06.727 に答える