2016-07-19 5 views
0

Also habe ich eine komprimierte Liste mit Lauflängencodierung erstellt. Jetzt versuche ich, Durchschnittswerte innerhalb bestimmter Variablen in der Liste zu finden (z. B. 450 und 180). Der Code sollte wie diese ArbeitMittelung zwischen ausgewählten Variablen in einer RLE-Liste, Probleme mit dem letzten Element

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

bin ich ziemlich neu in diesem sonst würde ich die Mittelung während meiner Kompression vorgeformten haben.

Woran ich festhalte, sind zwei Dinge: meine resultierende Liste, wenn unkomprimiert, ist nicht die gleiche Länge des Originals und ich bin unsicher, wie das letzte Element anhängen sollte, sollte der Code nicht durch den letzten else gehen. Ich könnte Indizierung innerhalb meiner for-Schleife mit etwas wie elif i[0].index==len(lst) verwenden, aber das wäre rechenintensiv (der Datensatz ist ziemlich groß). Was ich erstellt habe, ist eine endgültige if-Anweisung außerhalb der for-Schleife, aber die resultierende Liste hat immer noch nicht die gleiche Länge wie das Original.

Und nur für diejenigen, die das Problem später erforschen würden, habe ich meine Lösung hinzugefügt, die die Komprimierung und Mittelung kombiniert. Und um den Zweck zu verdeutlichen, komprimiere ich die Winkel zwischen den Straßensegmenten in einem GIS-Programm, um einen kleineren Datensatz zu erstellen. Die 450er können als Nullwerte behandelt werden.

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

nicht klar, was du erwartest. Sie sprechen über Listen gleicher Länge, aber die gewünschten Ergebnisse sind eine Liste von length == 4 aus einer Eingabe von len == 6. ** NB ** Sie haben eine "else" -Anweisung, die * immer * ausgewertet wird wenn das vorhergehende if/elif nicht erfüllt ist. Alle "i" werden durch den Block "if/elif/elif/else" verarbeitet. –

+0

Sorry, Länge ist definiert als die Addition aller i [1] in der Liste oder der einmal dekodierten Liste. –

+0

OK, warum passt Ihre Beispielausgabe (die vermutlich das ist, was Sie * erhalten sollen) nicht zusammen? der i [1] ergibt 12, gegenüber 11 in der ursprünglichen Eingabeliste. –

Antwort

0

Vorausgesetzt, dass Sie keine doppelten Einträge von 180 in der Ausgabe haben sollte, und Ihre erwartete Ausgabe lautet:

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

Ich denke, das wird es tun:

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

Ich habe das Problem schließlich gelöst, indem ich die Komprimierung mit kombiniert habe die Mittelung. –