2016-07-19 4 views
0

그래서 런타임 길이 인코딩을 사용하여 압축 된 목록을 만들었습니다. 이제 목록의 특정 변수 내에서 평균을 찾으려고합니다 (예 : 450180). 이 코드는 다음과 같이 작동해야합니다.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)과 같은 색인을 사용할 수는 있지만 계산 비용이 많이들 것입니다 (데이터 집합이 다소 큽니다). 내가 작성한 것은 for 루프 외부의 최종 if 문이지만 결과 목록은 여전히 ​​원본과 길이가 다릅니다.

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) 

나중에 문제를 연구 할 사람들을 위해 압축과 평균화를 결합한 솔루션을 추가했습니다. 그리고 목적을 명확히하기 위해 GIS 프로그램에서 도로 구간 사이의 각도를 압축하여 더 작은 데이터 세트를 만듭니다. 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

명확하지 무엇을 너는 기대하고있어. 같은 길이의리스트에 대해서 이야기하지만, 원하는 결과는 len == 6의 입력으로부터 길이 == 4의리스트입니다. ** NB ** 당신은 항상 평가 될'else' 문장을 가지고 있습니다. 앞의 if/elif가 충족되지 않은 경우. 모든'i'는'if/elif/elif/else' 블록에 의해 처리 될 것입니다. –

+0

죄송합니다. 길이는 목록에있는 모든 i [1] 또는 일단 디코딩 된 목록의 추가로 정의됩니다. –

+0

그렇다면 왜 당신의 예제 출력 (아마 당신이 * 받기를 원하는지)이 일치하지 않는 것일까? i [1]은 원래 입력 목록에서 11인데 반해 12로 합니다. –

답변

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

마지막으로 압축을 결합하여 문제를 해결했습니다. 평균. –