2016-07-19 4 views
0

Итак, я создал сжатый список с использованием кодировки длины пробега. Теперь я пытаюсь найти средние значения в определенных переменных в списке (например, 450 и 180). Код должен работать как этотУсреднение между выборами переменных в списке RLE, имеющими проблемы с последним элементом

a=[[180,3],[140,1],[160,1],[150,2],[450,1][180,4]] 
print mean(a) 
>[[180,3],[150,4],[450,1][180,4]] 

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

То, что я застрял, - это две вещи: мой результирующий список при несжатом - это не та же длина оригинала, и я не знаю, как добавить последний элемент, если код не пройдет через последний. Я мог бы использовать индексирование в моем цикле for с чем-то вроде elif i[0].index==len(lst), но это было бы дорого вычислительным (набор данных довольно велик). То, что я создал, является заключительным оператором if вне цикла for, но результирующий список по-прежнему не совпадает с оригиналом.

def mean(lst): 
    sm=0 
    count=0 
    new=[] 
    for i in lst: 
     if i[0] is None: 
      new.append([0,1]) 
     elif i[0]!=180.0 and i[0]!=450.0: 
      sm+=(i[0]*i[1]) 
      count+=i[1] 
     elif count==0: 
      new.append(i)  
     else: 
      new.append([sm/count,count]) 
      new.append(i) 
      count=0 
      sm=0 
    if count>0: 
     new.append([sm/count,count]) 
    pass  
    return (new) 

И только для тех, кто изучит эту проблему позже, я добавил мое решение, которое в сочетании сжатия и усреднение. Чтобы уточнить цель, я сжимаю углы между сегментами дороги в программе ГИС для создания меньшего набора данных. 450-е можно рассматривать как значения Null.

with arcpy.da.SearchCursor("test_loop",["angle3"]) as cursor: 
    count1 = 0 
    count2=0 
    count3=0 
    add=0 
    lst=[] 
    for row in cursor: 
     if row[0]<180 and row[0] is not None: 
      if count1>0: 
       lst.append([180,count1+count3]) 
       count1=0 
       count3=0 
       pass  
      count2+=1 
      add+=row[0] 
     elif row[0]==180: 
      if count2>0: 
       lst.append([add/count2,count2+count3]) 
       count2=0 
       count3=0 
       add=0 
       pass  
      count1+=1  
     elif row[0]==450 or row[0] is None: 
      count3+=1 
     else: 
      print "Error" 
      break 
    if count1>0: 
     lst.append([180,count1+count3]) 
     count1=0 
     count3=0 
    elif count2>0: 
     lst.append([add/count2,count2+count3]) 
     count2=0 
     count3=0 
     add=0 
    else: 
     lst.append([None,count3])      
    print lst 
    del cursor 
    del row 

def decode(lst): 
    q = [] 
    for i in lst: 
     for x in range(i[1]): 
      q.append (i[0]) 
    return q 

final=decode(lst) 
print final    

with arcpy.da.UpdateCursor("test_loop",["curve_level"]) as cursor: 
    i=0 
    for row in cursor: 
     row[0]=final[i] 
     i+=1 
     cursor.updateRow(row) 
del cursor 
del row 
+0

не ясно, что вы ожидаете. Вы говорите о списках одинаковой длины, но желаемые результаты, которые вы показываете, представляют собой список длины == 4 из ввода len == 6. ** NB ** у вас есть оператор 'else', который будет * всегда * быть оценен если предыдущие if/elif не выполняются. Все 'i' будут обрабатываться блоком' if/elif/elif/else'. –

+0

К сожалению, длина определяется как добавление всех i [1] в список или список после декодирования. –

+0

ОК, тогда почему ваш пример вывода (который предположительно является тем, что вы хотите получить *) не соответствует? i [1] суммируется до 12, против 11 в исходном списке ввода. –

ответ

0

Предполагая, что вы не должны иметь дубликаты записей из 180 в вашей продукции, и ожидаемая выход:

[[180,7],[150,4],[450,1]] 

Я думаю, что это будет делать:

from collections import defaultdict 
def mean(lst): 
    d = defaultdict(int) 
    sm, count = 0.0, 0 
    for [k, v] in lst: 
     if float(k) in [180.0,450.0]: 
      d[k] += v 
     else: 
      sm += k*v 
      count +=v 
    if sm != 0: d[sm/count] = count 
    return [list(itm) for itm in d.items()] 
+1

Я решил проблему окончательно, объединив сжатие с усреднение. –