2013-06-05 4 views
1

У меня есть список из 10 терминов с их оценками. Первые х имеют гораздо более важное значение, чем остальные. Поэтому я хочу найти x.Как «отрезать хвост» серии

Например, plotting this list показывает плато после третьего срока. Следовательно, мы сохраняем первые три члена. Даже интуитивно, сохраняя первые три условия, кажется уместным.

badge         => 7.00709342956543 
    unlocked        => 7.00709342956543 
    foursquare        => 5.830315748850505 
    https         => 5.001254081726074 
    you've unlocked       => 4.954763253529866 
    50xxxxxx badge       => 4.954763253529866 
    all badges        => 4.954763253529866 
    unlocked far       => 4.954763253529866 
    badges         => 4.954763253529866 
    just unlocked       => 4.954763253529866 

Но как генерировать эту отсечку программно? Я предпочитаю материал, доступный в стандартных библиотеках.

+0

Таким образом, я предполагаю, что одним из подходов было бы абс() разность терминов, упорядочить список различий в порядке убывания. Установите свою «пороговую» разницу (скажем, 2.5) и игнорируйте любую разницу <2.5 из списка. –

ответ

2

Я предполагаю, что ваши «термины» будут отсортированы в порядке убывания, как показано в примере, который вы предоставили. Я бы просто установил дельту (скажем, 0,5), которая представляет собой разницу, достаточно маленькую, чтобы быть неосведомленной.

Я бы прошел через набор терминов, добавляя их результирующую коллекцию, и как только я увижу термин в «дельта» моего ранее увиденного термина, я закончу свою итерацию и потенциально удалю последний замеченный термин из моя итоговая коллекция.

Это имеет смысл?

Что-то, что выглядит следующим образом:

delta = 0.5 
result = [] 
for term in termMapSortedKeys: 
    if (previousTermValue - delta >= termMap[term]): 
      break 
    else: 
      result.append(term) 
      previousTermValue = termMap[term] 
del result[-1] 
return result 
+1

Если вы хотите больше терминов, я бы предложил сделать дельта между этим элементом и одним 'k' вниз по списку. Таким образом, вы не можете остановиться на галстуке, но все равно остановитесь, как только список перестанет расти. – btilly

+0

@btilly: Вы абсолютно правы! Возможно, имеет смысл перемещаться по списку в противоположном направлении (по возрастанию порядка значений термина). Как только вы столкнетесь с термином со значением> previousTermValue + delta, вы начнете запись элементов. Я предполагаю, что самым большим недостатком такого подхода является то, что вы закончите читать целую кучу хлама, прежде чем попасть в мясо. –

0

Для станда Пба дружественного способа, вы можете использовать itertools.tee делать сравнение между элементами в списке и вернуть дельты как в итераторе. Затем захватите данные в пределах вашего допуска, используя itertools.takewhile.

import itertools, sys 

def delta(data): 
    '''yield the original data and the delta to the next item as tuple''' 
    a, b = itertools.tee(data) 
    yeild (next(b, None), sys.maxint) # assume the first item always passes :) 
    for n in itertools.izip(a, b): 
     yield n[1], abs(n[1] - n[0]) 


# example... 
data = [0,1,2,3,4,6,6.125,6.25,6.375,6,6,6.25,5,6,6, 4.5, 2.5, 7] 
data.sort()  
print data 
# [0, 1, 2, 2.5, 3, 4, 4.5, 5, 6, 6, 6, 6, 6, 6.125, 6.25, 6.25, 6.375, 7] 


filter_fn = lambda x: x[1] > .05 # tolerance goes here... 
trimmed = [item[0] for item in itertools.takewhile(filter_fn , delta(data))] 
print trimmed 
# [0, 1, 2, 2.5, 3, 4, 4.5, 5, 6] 
Смежные вопросы