ビルドオフと以前の質問:シングルパスでのジェネレーターの統計の計算。パイソン
前に述べたように、単一パスでジェネレーターから統計を計算することは非常に高速で、メモリ効率が高くなります。90 パーセンタイルや n 番目に小さいものなどの複雑な統計とランク属性は、多くの場合、標準偏差と平均 (上記で解決) よりも複雑な作業を必要とします。これらのアプローチは、map/reduce ジョブや、データをリストに入れたり、複数のパスを計算したりするのが非常に遅くなる大規模なデータセットを操作する場合に非常に重要になります。
以下は、ランク順に基づいてデータを検索するための O(n) クイックソート スタイルのアルゴリズムです。中央値、パーセンタイル、四分位数、十分位数を見つけるのに役立ちます。データが既にソートされている場合は、data[n] と同等です。ただし、分割/ピボットできるリスト内のすべてのデータが必要です。
単一パスでジェネレーターを使用して、中央値、パーセンタイル、四分位数、および十分位数を計算するにはどうすればよいですか?
完全なリストを必要とするクイックソート スタイルのアルゴリズム
import random
def select(data, n):
"Find the nth rank ordered element (the least value has rank 0)."
data = list(data)
if not 0 <= n < len(data):
raise ValueError('not enough elements for the given rank')
while True:
pivot = random.choice(data)
pcount = 0
under, over = [], []
uappend, oappend = under.append, over.append
for elem in data:
if elem < pivot:
uappend(elem)
elif elem > pivot:
oappend(elem)
else:
pcount += 1
if n < len(under):
data = under
elif n < len(under) + pcount:
return pivot
else:
data = over
n -= len(under) + pcount