如何让移动窗口更快?

发布于 2025-01-11 05:39:08 字数 1663 浏览 0 评论 0原文

我使用移动窗口来缓冲栅格数据(numpy 数组)。它非常慢,我想知道是否可以改进代码以使其更快: 我的实际数组的形状为 (1349, 1368),由零和一组成。

import numpy as np

clouds = np.array([[[0, 0, 0, 0, 0], 
                    [0, 0, 0, 1, 0],
                    [0, 0, 1, 1, 1],
                    [0, 0, 0, 0, 1],
                    [0, 0, 0, 0, 1],
                    ]])  

cloudShadow = np.array([[[1, 0, 0, 1, 1], 
                         [0, 1, 1, 0, 0],
                         [0, 1, 0, 0, 0],
                         [0, 0, 0, 0, 0],
                         [0, 0, 0, 0, 1],
                         ]])

row_up_cloudShadow = 1      
row_low_cloudShadow = 0     
col_left_cloudShadow = 1  
col_right_cloudShadow = 0 


row = []
for i in range(len(np.where(clouds == 1)[0])):
    row_xy = list(range((np.where(clouds == 1)[0][i] - row_up_cloudShadow), (np.where(clouds == 1)[0][i] + row_low_cloudShadow) +1))
    row.append(row_xy)


col = []
for i in range(len(np.where(clouds == 1)[1])):
    col_xy = list(range((np.where(clouds == 1)[1][i] - col_left_cloudShadow), (np.where(clouds == 1)[1][i] + col_right_cloudShadow) +1))
    col.append(col_xy)

buffer = []
for i in range(0, np.count_nonzero(clouds == 1)):
    
    for j in range(len(row[0])):
        z = row[i][j]
        
        for u in range(len(col[0])):
            s = col[i][u]
            
            buffer.append(np.array([z,s]))

buffer = np.asarray(buffer)
buffer = np.where(buffer < 0, 0, buffer)

data_buff_cloudShadow = np.zeros(clouds.shape)
for i in range(len(buffer)):
    data_buff_cloudShadow[buffer[i][0]][buffer[i][1]] = 1

cloudShadow_buff = np.where(data_buff_cloudShadow == 1, cloudShadow, 0)

I use a moving window to buffer raster data (numpy array). It is very slow and I am wondering if it is possible to improve the code to make it faster:
My actual arrays have the shape (1349, 1368) and consist of zeros and ones.

import numpy as np

clouds = np.array([[[0, 0, 0, 0, 0], 
                    [0, 0, 0, 1, 0],
                    [0, 0, 1, 1, 1],
                    [0, 0, 0, 0, 1],
                    [0, 0, 0, 0, 1],
                    ]])  

cloudShadow = np.array([[[1, 0, 0, 1, 1], 
                         [0, 1, 1, 0, 0],
                         [0, 1, 0, 0, 0],
                         [0, 0, 0, 0, 0],
                         [0, 0, 0, 0, 1],
                         ]])

row_up_cloudShadow = 1      
row_low_cloudShadow = 0     
col_left_cloudShadow = 1  
col_right_cloudShadow = 0 


row = []
for i in range(len(np.where(clouds == 1)[0])):
    row_xy = list(range((np.where(clouds == 1)[0][i] - row_up_cloudShadow), (np.where(clouds == 1)[0][i] + row_low_cloudShadow) +1))
    row.append(row_xy)


col = []
for i in range(len(np.where(clouds == 1)[1])):
    col_xy = list(range((np.where(clouds == 1)[1][i] - col_left_cloudShadow), (np.where(clouds == 1)[1][i] + col_right_cloudShadow) +1))
    col.append(col_xy)

buffer = []
for i in range(0, np.count_nonzero(clouds == 1)):
    
    for j in range(len(row[0])):
        z = row[i][j]
        
        for u in range(len(col[0])):
            s = col[i][u]
            
            buffer.append(np.array([z,s]))

buffer = np.asarray(buffer)
buffer = np.where(buffer < 0, 0, buffer)

data_buff_cloudShadow = np.zeros(clouds.shape)
for i in range(len(buffer)):
    data_buff_cloudShadow[buffer[i][0]][buffer[i][1]] = 1

cloudShadow_buff = np.where(data_buff_cloudShadow == 1, cloudShadow, 0)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

絕版丫頭 2025-01-18 05:39:08

以下是一些使您的代码更快的具体准则:

  1. 避免重复相同的计算:在前两个循环中执行相同的计算 (np.where(clouds == 1)) 多次,以便您可以重构为:
row_idxs, col_idxs = np.where(clouds == 1)

for ridx in row_idxs:
    row_xy = list(
        range(ridx - row_up_cloudShadow, ridx + row_low_cloudShadow +1)
    )
    row.append(row_xy)

for cidx in col_idxs:
    col_xy = list(
        range(cidx - col_left_cloudShadow, cidx + col_right_cloudShadow +1)
    )
    col.append(col_xy)
  1. 尽可能删除循环:仅使用 Numpy 功能可以完成的任何操作都会更快。在这里,使用 Numpy 索引可以避免最后一个 for 循环:
data_buff_cloudShadow = np.zeros(clouds.shape)
data_buff_cloudShadow[buffer[:, 0], buffer[:, 1]] = 1
  1. 尽可能避免 Python list 数据类型和 Numpy 的 ndarray 之间的转换。这特别适用到中间结果。尝试用完整数组重新想象你的问题,因为很多问题都可以用这种方式表示。在这里,您也许可以使用 np.meshgrid来表示坐标更容易。

对于移动窗口,您可能会受益于查看 numpy.lib。 stride_tricks.sliding_window_view 用于直接内置于 Numpy 中的移动窗口。

有关更多非常有用的信息,请参阅 https://numpy.org/learn/

Here are some specific guidelines to make your code faster:

  1. Avoid repeating the same calculation: In your first two loops you do the same calculation (np.where(clouds == 1)) many times, so that you could refactor to:
row_idxs, col_idxs = np.where(clouds == 1)

for ridx in row_idxs:
    row_xy = list(
        range(ridx - row_up_cloudShadow, ridx + row_low_cloudShadow +1)
    )
    row.append(row_xy)

for cidx in col_idxs:
    col_xy = list(
        range(cidx - col_left_cloudShadow, cidx + col_right_cloudShadow +1)
    )
    col.append(col_xy)
  1. Remove loops wherever possible: Anything you can do with only Numpy functionality will be faster. Here, the last for-loop can be avoided using Numpy indexing:
data_buff_cloudShadow = np.zeros(clouds.shape)
data_buff_cloudShadow[buffer[:, 0], buffer[:, 1]] = 1
  1. Avoid conversions between Pythons list datatype and Numpy's ndarray whenever possible. This specifically applies to intermediate results. Try to re-imagine your problem in terms of full arrays, as quite a number of problems can be represented that way. Here, you might be able to use np.meshgrid to represent coordinates easier.

For moving windows, you might benefit from looking into numpy.lib.stride_tricks.sliding_window_view for a moving window directly built into Numpy.

For further very helpful information, see https://numpy.org/learn/.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文