Случайным образом выборки населения и учета средств: прибраться, обобщать, документ?


Это отчасти ответ на переполнение стека вопрос. ОП нужен способ, чтобы выполнить расчеты на выборках из популяции, но был наезд ошибки памяти из-за сохранения образцов в памяти.

Функции основано на части случайным образом.образца, но только код филиала, используя набор присутствует.

Если мы сможем привести в порядок и комментировать это достаточно хорошо, это может быть стоит публиковать как рецепт на Питон книга рецептов.

import random

def sampling_mean(population, k, times):
    # Part of this is lifted straight from random.py
    _int = int
    _random = random.random

    n = len(population)
    kf = float(k)
    result = []

    if not 0 <= k <= n:
        raise ValueError, "sample larger than population"

    for t in xrange(times):
        selected = set()
        sum_ = 0
        selected_add = selected.add

        for i in xrange(k):
            j = _int(_random() * n)
            while j in selected:
                j = _int(_random() * n)
            selected_add(j)
            sum_ += population[j]

        # Partial result we're interested in
        mean = sum_/kf
        result.append(mean)
    return result

sampling_mean(x, 1000000, 100)

Может быть, это было бы интересно обобщить его, так что вы можете передать функцию, которая вычисляет значение интересующего вас образца?



2342
8
задан 25 января 2011 в 11:01 Источник Поделиться
Комментарии
1 ответ

Делая версию генератор случайных.образец() вроде бы идея получше.

from __future__ import division
from random import random
from math import ceil as _ceil, log as _log

def xsample(population, k):
"""A generator version of random.sample"""
n = len(population)
if not 0 <= k <= n:
raise ValueError, "sample larger than population"
_int = int
setsize = 21 # size of a small set minus size of an empty list
if k > 5:
setsize += 4 ** _ceil(_log(k * 3, 4)) # table size for big sets
if n <= setsize or hasattr(population, "keys"):
# An n-length list is smaller than a k-length set, or this is a
# mapping type so the other algorithm wouldn't work.
pool = list(population)
for i in xrange(k): # invariant: non-selected at [0,n-i)
j = _int(random() * (n-i))
yield pool[j]
pool[j] = pool[n-i-1] # move non-selected item into vacancy
else:
try:
selected = set()
selected_add = selected.add
for i in xrange(k):
j = _int(random() * n)
while j in selected:
j = _int(random() * n)
selected_add(j)
yield population[j]
except (TypeError, KeyError): # handle (at least) sets
if isinstance(population, list):
raise
for x in sample(tuple(population), k):
yield x

Принимая среднее выборки становится тривиальным:

def sampling_mean(population, k, times):
for t in xrange(times):
yield sum(xsample(population, k))/k

Тем не менее, анализ кода, не многое можно сказать о код, как это более или менее принимает непосредственно от источника Python, который может быть сказал, чтобы быть авторитетным. ;) Есть много глупых ускорений, что делает код труднее читать...

2
ответ дан 31 января 2011 в 03:01 Источник Поделиться