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

如何按条件填充numpy数组中的零值(通用方案)

解决NumPy数组中零值向前填充前一个非零值的通用方案

针对你提出的需求——把数组中任意列的零值替换为前一个最近的非零值,且开头的零保持不变,我准备了两种实现方案,都具备通用性,能处理各种列的零值填充场景(比如全零列、中间零散零值等)。

方案1:直观循环实现(适合小数据集)

这个方案逻辑清晰,容易理解,适合数据量不大的场景:

import numpy as np

def forward_fill_zeros(arr):
    # 复制原数组,避免修改原始数据
    filled_arr = arr.copy()
    # 遍历每一列进行处理
    for col in range(arr.shape[1]):
        current_col = filled_arr[:, col]
        # 找到当前列所有非零值的索引
        non_zero_indices = np.where(current_col != 0)[0]
        
        # 如果该列全是零,直接跳过
        if len(non_zero_indices) == 0:
            continue
        
        # 填充两个非零值之间的零
        for i in range(len(non_zero_indices)-1):
            start = non_zero_indices[i] + 1
            end = non_zero_indices[i+1]
            filled_arr[start:end, col] = current_col[non_zero_indices[i]]
        
        # 填充最后一个非零值之后的所有零
        last_idx = non_zero_indices[-1]
        filled_arr[last_idx+1:, col] = current_col[last_idx]
    
    return filled_arr

验证你的示例

用你提供的数组测试:

# 原数组
myArray = np.array( [[ 976.77 , 152.95 , 105.62 , 53.44 , 0 ], [ 987.61 , 156.63 , 105.53 , 51.1 , 0 ], [1003.74 , 151.31 , 104.435, 52.86 , 0 ], [ 968. , 153.41 , 106.24 , 58.98 , 0 ], [ 978.66 , 152.19 , 103.28 , 57.97 , 0 ], [1001.9 , 152.88 , 105.08 , 58.01 , 0 ], [1024.93 , 146.59 , 107.06 , 59.94 , 0 ], [1020.01 , 148.05 , 109.96 , 58.67 , 0 ], [1034.01 , 152.69 , 107.64 , 59.74 , 0 ], [ 0. , 154.88 , 102. , 58.96 , 0 ], [ 0. , 147.46 , 100.69 , 54.95 , 0 ], [ 0. , 149.7 , 102.439, 53.91 , 0 ]] )

# 执行填充
myArrayEnd = forward_fill_zeros(myArray)

# 验证是否符合预期
expected = np.array( [[ 976.77 , 152.95 , 105.62 , 53.44 , 0 ], [ 987.61 , 156.63 , 105.53 , 51.1 , 0 ], [1003.74 , 151.31 , 104.435, 52.86 , 0 ], [ 968. , 153.41 , 106.24 , 58.98 , 0 ], [ 978.66 , 152.19 , 103.28 , 57.97 , 0 ], [1001.9 , 152.88 , 105.08 , 58.01 , 0 ], [1024.93 , 146.59 , 107.06 , 59.94 , 0 ], [1020.01 , 148.05 , 109.96 , 58.67 , 0 ], [1034.01 , 152.69 , 107.64 , 59.74 , 0 ], [1034.01 , 154.88 , 102. , 58.96 , 0 ], [1034.01 , 147.46 , 100.69 , 54.95 , 0 ], [1034.01 , 149.7 , 102.439, 53.91 , 0 ]] )

print(np.allclose(myArrayEnd, expected))  # 输出 True

方案2:向量化实现(适合大数据集)

如果你的数组数据量很大,循环会影响效率,这个向量化方案利用NumPy的内置函数实现,速度更快:

import numpy as np

def forward_fill_zeros_vectorized(arr):
    filled_arr = arr.copy()
    for col in range(arr.shape[1]):
        col_data = filled_arr[:, col]
        # 标记非零值的位置
        mask = col_data != 0
        # 用累积最大值的方式,将非零值向后填充覆盖零值
        # 先把非零值保留,零值暂时设为0,然后累积取最大(非零值会保留并覆盖后面的零)
        filled_vals = np.zeros_like(col_data)
        filled_vals[mask] = col_data[mask]
        filled_arr[:, col] = np.maximum.accumulate(filled_vals)
    
    return filled_arr

这个方案的核心是np.maximum.accumulate,它会沿着列方向累积取最大值,由于非零值都大于零(如果你的场景存在负数值,可以调整为用索引标记的方式实现),所以能完美实现向前填充的效果。

通用性说明

这两个函数都能处理任意NumPy数组:

  • 如果某列全是零,函数会跳过该列,保持原数据不变;
  • 如果某列中间有零散零值,会自动填充为前一个最近的非零值;
  • 如果零值出现在数组开头,会保持为零(因为没有前一个非零值可以填充)。

内容的提问来源于stack exchange,提问作者lee.edward01

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 09:08:34