You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何高效过滤0值无效值并实现多数组对应位置求平均?

优化方案

你现有代码慢的核心原因是用了两层Python原生循环逐元素遍历数组,Python循环的执行开销极高,完全没有利用numpy的向量化运算能力——numpy的向量化操作会把运算下沉到C层面执行,同等逻辑速度比Python循环快2个数量级左右。

你的计算逻辑本身没问题,只需要把所有内层逐元素遍历的Python循环替换成numpy向量化操作即可,不需要改动整体流程:

  • 对每个读入的LST数组,直接生成布尔型的有效位掩码(值非0的位置为True,0值位置为False)
  • 求和数组直接累加「原数组 * 掩码」的结果,0值位置自然不会贡献累加值
  • 计数数组直接累加掩码本身(True会被当作1,False当作0,刚好统计每个位置的有效值个数)
  • 最终求平均的步骤也用numpy的带条件除法实现,自动跳过分母为0的位置

优化后的完整代码如下:

from pyhdf.SD import SD, SDC
import numpy as np
import os

a, b = lst_template.shape
sum_arr = np.zeros((a, b), dtype=np.float64)
denominator_arr = np.zeros((a, b), dtype=np.int32)

for filename in os.listdir(file_location):
    file_path = os.path.join(file_location, filename)
    try:
        file = SD(file_path)
        lst = file.select('LST').get()
        if lst.shape != (a, b):
            print(f'shape incorrect {filename}')
            continue
        # 向量化操作替代双层Python循环
        valid_mask = lst != 0
        sum_arr += lst * valid_mask
        denominator_arr += valid_mask
        print(filename)
    except Exception as e:
        print(e)
        print(filename)

# 逐位置求平均,分母为0的位置默认输出0
result_arr = np.divide(
    sum_arr,
    denominator_arr,
    out=np.zeros((a, b), dtype=np.float32),
    where=denominator_arr != 0
)

可选进一步优化

如果你的单景LST数组尺寸不大,内存足够放下全部800景数组,可以用更简洁的np.nanmean实现,连手动维护求和、计数数组的步骤都可以省掉:

valid_lst_list = []
for filename in os.listdir(file_location):
    # 省略文件读入、形状校验、异常捕获逻辑,和前面一致
    # 把形状符合要求的lst加入列表
    if lst.shape == (a, b):
        valid_lst_list.append(lst)

# 堆叠为三维数组,把0值替换为nan后沿新维度求均值,自动跳过nan
all_lst = np.stack(valid_lst_list, axis=0).astype(np.float64)
all_lst[all_lst == 0] = np.nan
result_arr = np.nanmean(all_lst, axis=0)

这个写法代码更短,但是会额外占用存储全部数组的内存,如果单景数组尺寸很大(比如单景几GB)就不适合,用前面逐文件累加的方案内存占用固定,和文件总数无关,稳定性更好。

另外注意几个细节:

  • 累加求和的数组建议用float64类型,避免800组数据累加后出现数值溢出
  • 路径拼接不要直接用字符串相加,用os.path.join可以避免跨平台的路径分隔符问题

内容的提问来源于stack exchange,提问作者FarmerZee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 00:36:28