2013-11-27 2 views
1

Мне нужно найти подсписцы набора вероятностей, так что сумма отрицательного двоичного логарифма подписок будет равна 1 (или просто минута 1,0). Просто найти первый такой подсписк будет хорошо.Уступка при принятии частичных сумм

Для этого я думал, что могу использовать takewhile и генераторные выражения, но я не могу заставить работать.

До сих пор у меня есть:

from itertools import takewhile 
from numpy.random import dirichlet 
from math import log 

def partial_sums(iterable): 
    total = 0 
    for i in iterable: 
     total += -1*log(i,2) 
     yield total 

probs = dirichlet([1]*1000).tolist() 
probs = 10*probs 
ps = partial_sums(probabilities) 
s = takewhile(lambda x: x<1, sum(x for x in partial_sums(probs))) 

Это просто дает мне пустой список, однако.

EDIT: Если я использую Python 3. Я мог бы использовать itertools.accumulate:

s = takewhile(lambda x: x<1, itertools.accumulate(math.log(x,2) for x in probs)) 

Я ищу для Python 2.7 эквивалента.

EDIT: Я думал, что это:

def partial_sums(iterable): 
    total = 0 
    for i in iterable: 
     total += -1*log(i,2) 
     if total >= 1.0: 
      yield i 

будет работать, но, увы, это не так.

+0

Вы используете 'sum()', что возвращает * одно значение *. Это не является итерабельным для 'takewhile()' для перебора и приведет к ошибке. Откуда происходит 'sum()', если он не является встроенным? –

+0

Также вы хотели использовать 'partial_sums (probs)' вместо 'partial_sums (probabilities)'? –

+0

Ваше ** первое ** значение уже превышает 1; 'next (ps)' возвращает '12.091043076201494'. –

ответ

0

Я нашел решение:

from itertools import takewhile 
from numpy.random import dirichlet 
from math import log 

def partial_sums(iterable): 
    total = 0 
    for i in iterable: 
     total += i 
     yield total 

probs = dirichlet([1]*1000).tolist() 
probs = 10*probs 
s = takewhile(lambda x: x<1, partial_sums(-1*log(x,2) for x in probs)) 

EDIT: Как было отмечено Martijn Питерс, документация для itertools.accumulate содержит следующую функцию, которая прекрасно работает на Python 2:

def accumulate(iterable, func=operator.add): 
    'Return running totals' 
    # accumulate([1,2,3,4,5]) --> 1 3 6 10 15 
    # accumulate([1,2,3,4,5], operator.mul) --> 1 2 6 24 120 
    it = iter(iterable) 
    total = next(it) 
    yield total 
    for element in it: 
     total = func(total, element) 
     yield total 

Этот следует использовать вместо partial_sums() в вышеприведенном решении.

Смежные вопросы