そこで、ランレングス エンコーディングを使用して圧縮リストを作成しました。450
現在、リスト内の特定の変数 (と など)内で平均を見つけようとしています180
。コードは次のように動作するはずです
a=[[180,3],[140,1],[160,1],[150,2],[450,1][180,4]]
print mean(a)
>[[180,3],[150,4],[450,1][180,4]]
私はこれにかなり慣れていません。そうでなければ、圧縮中に平均化を行っていたでしょう。
私が立ち往生しているのは2つのことです。圧縮されていないときの結果のリストは元のリストと同じ長さではなく、コードが最後の要素を通過しない場合に最後の要素を追加する方法がわかりません。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