2015-04-30 41 views
2

不是最精明的python用戶,我一直在試圖找到一種解決方案來加速我的代碼。 我有2個光柵文件,都具有相同的尺寸和範圍。一個柵格是一條從激光雷達圖像中提取的河流,其高程值範圍很窄,河流文件中的所有其他值都是0.所以基本上,除了河流寬度(具有高程數據的像素)之外,99%河流柵格的值爲0.另一個柵格文件是從激光雷達圖像中提取的,並在整個範圍內具有高程數據。Python - 在光柵單元上循環,速度極慢

我的計劃是檢查沒有0值的河流文件中的每個像素,將其加1(如果河水水位上升1米),並將其與相鄰像素高程數據(基本上LIDAR標高的像素位置)。如果它更高,給它一個值1(這意味着這個像素被淹沒)。 我想出了一些代碼,但它看起來很可怕,而且非常緩慢(油漆幹得比代碼運行得更快)。 所以我正在尋找一種加快速度的方法。我看矢量化,numpy等,但還不能理解它(可能是因爲我已經在工作超過9小時..)

所以,在這裏,它的任何建議將非常多讚賞:

river = arcpy.Raster(r'C:\Flood.gdb\Clip_River1') 
lidar = arcpy.Raster(r'C:\Flood.gdb\Clip_Lidar_1') 

arrayRiver = arcpy.RasterToNumPyArray(river,nodata_to_value=0) 
(rHeight, rWidth)=arrayRiver.shape 

arrayLidar = arcpy.RasterToNumPyArray(lidar,nodata_to_value=0) 
(lHeight, lWidth)=arrayLidar.shape 

# extent of the 2 rasters: columns 3822, rows 10129 

flood = 1 
while flood == 1: 
    flood = 0 
    for row in range(0,rHeight-1): 
     for col in range(0,rWidth-1): 
      if arrayRiver.item(row,col) <> 0 and arrayRiver[row,col] <> 1: 
       if arrayLidar[row,col-1] <> 1 and arrayLidar.item(row,col-1) < arrayRiver.item(row,col)+1: 
        arrayLidar[row,col-1] = 1 
        arrayRiver[row,col-1] = arrayRiver.item(row,col) 
        flood = 1 

       [....doing the same concept for each possible neighboring pixel] 

       if arrayLidar[row+1,col+1] <> 1 and arrayLidar.item(row+1,col+1) < arrayRiver.item(row,col)+1: 
        arrayLidar[row+1,col+1] = 1 
        arrayRiver[row+1,col+1] = arrayRiver.item(row,col) 
        flood = 1 

      arrayRiver[row,col] = 1 

newRaster = arcpy.NumPyArrayToRaster(arrayLidar,lowerLeft,cellSize,value_to_nodata=0) 
newRaster.save(r"C:\Flood.gdb\newRastaRiver_small") 

newEmptyRaster = arcpy.NumPyArrayToRaster(arrayEmpty,lowerLeft,cellSize,value_to_nodata=0) 
newEmptyRaster.save(r"C:\Flood.gdb\newEmptyRastaRiver_small") 
+0

在做任何事情之前,你應該做一個分析,拋出整個if語句,看看你的代碼在本地生效了多長時間,然後你就可以看到主要瓶頸在哪裏。而且你沒有添加單元格的尺寸,所以它不清楚瓶頸可能來自哪裏。 – user1767754

+1

我會問這個gis.stackexchange.com。一般來說,不要循環訪問數組。作爲一個例子,這裏有一個最近的問題,我問了每個元素的所有鄰居沒有循環:http://stackoverflow.com/questions/29925684/generalize-stacking-of-array-elements-neighbors-into-3 -d-array –

+0

好的,我刪除了整個if語句,整個代碼(包括柵格到數組語句)在8.2秒內運行。光柵的尺寸是3822列,10129行 – derBrain

回答

1

這只是一個部分的答案,但應該讓你開始。

使用numpy排除(掩碼)低值的所有像素。

arrayRiver = arcpy.RasterToNumPyArray(river,nodata_to_value=0) 
# Create a any array makring pixels less than zero. 
mask = arrayRiver > 0 
arrayRiver = arrayRiver[mask] 
arrayLidar = arrayLidar[mask] 

你arrayRiver & arrayLidar現在要小很多,和你的代碼的其餘部分應該會更快。順便說一句,你的示例代碼似乎沒有做一個arrayLidar數組。

+0

另外,歡迎來到Stack Overflow。 –

+0

感謝您的輸入Don。 我試過你的建議,但看起來 'arrayRiver = arrayRiver [mask]' line會創建一個列表(如果我錯了,請糾正我),並且我無法訪問原始位置(行,列)它再次與lidarArray [row,col]標高比較。 – derBrain