2016-10-22 7 views
0

Я пытаюсь найти последовательности из 200 меток и вернуть их индексы. Вот моя первая попытка, но я уверен, что должен быть лучший способ (быстрее) ...Как найти индексы последовательности значений в списке?

Последовательности должны быть кратными 200, а следующая последовательность меньше 200, а затем отклонять.

This image shows what my code does at the moment with labels at the top and indexes on the bottom

Для задачи обработки сигналов. Новое для python.

indexs = [] 
zeros = [0]*200 
ones = [1]*200 
twos = [2]*200 
threes = [3]*200 
fours = [4]*200 
fives = [5]*200 
i=0 
while i < range(len(labels)): 

    if i+200 > len(labels): 
     break 

    if labels[i:i+len(zeros)] == zeros: 
     indexs.extend((range(i,i+len(zeros)))) 
     i+=200 
     continue 
    if labels[i:i+len(ones)] == ones: 
     indexs.extend((range(i,i+len(zeros)))) 
     i+=200 
     continue 
    if labels[i:i+len(twos)] == twos: 
     indexs.extend((range(i,i+len(zeros)))) 
     i+=200 
     continue 
    if labels[i:i+len(threes)] == threes: 
     indexs.extend((range(i,i+len(zeros)))) 
     i+=200 
     continue 
    if labels[i:i+len(fours)] == fours: 
     indexs.extend((range(i,i+len(zeros)))) 
     i+=200 
     continue 
    if labels[i:i+len(fives)] == fives: 
     indexs.extend((range(i,i+len(zeros)))) 
     i+=200 
     continue 
    i+=1 

EDIT:

Спасибо за все отзывы людей, он высоко ценится. Я думаю, что я должен упомянуть, что я работаю с массивами размером 1M + и плотными в том, что они в основном являются блоками по 200. Поэтому я думал, что цикл while позволит мне пропускать большинство циклов. Часть моего плана состоит в том, чтобы уменьшить размерность, усреднив эти 200 блоков, но также создать ряд функций для классификатора. Я следую аналогичному методу в статье http://www.cis.fordham.edu/wisdm/includes/files/sensorKDD-2010.pdf.

Вот подобные (но меньше) сгенерированные данные

labels = [0]*1250+[1]*15400+[0]*12245+[5]*1204*[4]*20045  

Edit2: Heres некоторые аккуратнее код принимая некоторые из ваших советов

def tensequencer(df): 
    labels = df.activity.as_matrix().tolist() 
    #find and store all indexs 
    indexs = [] 
    zeros = [0]*200 
    ones = [1]*200 
    twos = [2]*200 
    threes = [3]*200 
    fours = [4]*200 
    fives = [5]*200 
    numbers = [zeros, ones, twos, threes, fours, fives] 
    i=0 
    while i < range(len(labels)): 

     if i+200 > len(labels): 
      break 

     if labels[i:i+200] in numbers : 
      indexs.extend((range(i,i+len(zeros)))) 
      i+=200 
      continue 

     i+=1 


    #index dataframe 


    df = df.iloc[indexs,:] 
    df.index=range(df.shape[0]) 
    return df 
+0

Ну, каждый 'if' имеет точно такое же содержание, так что может быть, что-то не так. – TigerhawkT3

+0

Вы не инициализировали ** ярлыки ** в этом коде и не выдавали никакого вывода. Не то, что мы можем воспроизвести. – Prune

ответ

0

Сканирование через этикетки, отслеживать, сколько времени последовательность идентичных чисел, заканчивается текущим значением. Всякий раз, когда эта последовательность соответствует вашим критериям (т. Е. Достаточно длинная), добавьте ее в индексы.

Одна морщина: скажем, что существует пробег 400 3. Из вашего описания не ясно, следует ли считать это 2 последовательности из 200 или 1 из 400 или обоих. Если только самое длинное, то не решайте добавлять к индексам до окончания прогона.

0

Вы знаете заранее, сколько итераций вам необходимо: использовать для цикла:

for i in range(len(labels) - 200): 

Это устраняет ваш перерыв заявление.

Далее у вас есть шесть почти идентичных наборов проверочных последовательностей. Отбросьте все шесть в один список (списков), и вы можете запустить диапазон циклов (6) для проверок ваших меток.

Еще лучше, вы знакомы с map и уменьшить? Вы можете сделать хороший однострочный чек, задав вопрос: каждый элемент в метках [i + 1: i + 200] равен ярлыкам [0]. Это устранит шестикратную проверку.

Это вас заводит?

0

Я не буду обсуждать алгоритм, просто внеся корректировки кода. Вы можете использовать наборы, чтобы проверить, не составлен ли список из 200 элементов из одного повторяющегося элемента.

for i in range(len(labels) - 200): 
    interval = labels[i:i+200] 
    reduced = set(interval) 
    if len(reduced) == 1: 
     repeated_number = reduced.pop() 

    # You have founded the number repeated 200 times consecutively. 
    # Now do whatever you wish with it. 
0

Не уверен, если это будет быстрее в плане исполнения, но это определенно будет лучше поддерживать:

indexs = [] 
for i in range(len(labels)): 
    if i+200 > len(labels): 
     break 
    for j in range(0,6): 
     cset = [j] * 200 
     if labels[i:i+len(cset)] == cset: 
      indexs.extend((range(i,i+len(cset)))) 
      i += 200 
      break