为了账号安全,请及时绑定邮箱和手机立即绑定

屏蔽 Numpy 数组并在不使用 for 循环的情况下对每个掩码应用计算

屏蔽 Numpy 数组并在不使用 for 循环的情况下对每个掩码应用计算

哈士奇WWW 2021-11-09 19:55:54
假设我们有以下数据数组:data_array = np.array([[1, 1, 1], [1, 1, 2], [2, 2, 2], [3, 3, 3], [4, 4, 4]], np.int16)data_arrayarray([[1, 1, 1],       [1, 1, 2],       [2, 2, 2],       [3, 3, 3],       [4, 4, 4]])我们希望根据以下范围屏蔽数组,以便能够对屏蔽部分应用计算:intervals = [[1, 2], [2, 3], [3, 4]]我们首先基于数据数组创建一个空数组和掩码,以便我们可以组合每个掩码数组的结果:init = np.zeros((data_array.shape[0], data_array.shape[1]))result_array = np.ma.masked_where((init == 0), init)result_arraymasked_array(data=[[--, --, --],      [--, --, --],      [--, --, --],      [--, --, --],      [--, --, --]],mask=[[ True,  True,  True],      [ True,  True,  True],      [ True,  True,  True],      [ True,  True,  True],      [ True,  True,  True]]有了这个,我们可以启动一个 for 循环,根据区间范围屏蔽数组,对屏蔽数组执行计算并将结果组合到单个结果数组中:for inter in intervals:    # Extact the start and en values for interval range    start_inter = inter[0]    end_inter = inter[1]    # Mask the array based on interval range    mask_init = np.ma.masked_where((data_array > end_inter), data_array)    masked_array = np.ma.masked_where((mask_init < start_inter), mask_init)    # Perform a dummy calculation on masked array    outcome = (masked_array + end_inter) * 100    # Combine the outcome arrays    result_array[result_array.mask] = outcome[result_array.mask]结果如下:array([[300.0, 300.0, 300.0],      [300.0, 300.0, 400.0],      [400.0, 400.0, 400.0],      [600.0, 600.0, 600.0],      [800.0, 800.0, 800.0]])我的问题是,如何在不使用 for 循环的情况下实现相同的结果?因此,在单个操作中对整个 data_array 应用屏蔽和计算。请注意,计算的变量随每个掩码而变化。是否可以对这个问题应用矢量化方法?我想numpy_indexed可能会有所帮助。谢谢你。
查看完整描述

1 回答

?
小唯快跑啊

TA贡献1863条经验 获得超2个赞

如果可以使间隔不重叠,那么您可以使用这样的函数:


import numpy as np


def func(data_array, intervals):

    data_array = np.asarray(data_array)

    start, end = np.asarray(intervals).T

    data_array_exp = data_array[..., np.newaxis]

    mask = (data_array_exp >= start) & (data_array_exp <= end)

    return np.sum((data_array_exp + end) * mask * 100, axis=-1)

在这种情况下,结果应该与原始代码相同:


import numpy as np


def func_orig(data_array, intervals):

    init = np.zeros((data_array.shape[0], data_array.shape[1]))

    result_array = np.ma.masked_where((init == 0), init)

    for inter in intervals:

        start_inter = inter[0]

        end_inter = inter[1]

        mask_init = np.ma.masked_where((data_array > end_inter), data_array)

        masked_array = np.ma.masked_where((mask_init < start_inter), mask_init)

        outcome = (masked_array + end_inter) * 100

        result_array[result_array.mask] = outcome[result_array.mask]

    return result_array.data


data_array = np.array([[1, 1, 1], [1, 1, 2], [2, 2, 2], [3, 3, 3], [4, 4, 4]], np.int16)

intervals = [[1, 1.9], [2, 2.9], [3, 4]]

print(np.allclose(func(data_array, intervals), func_orig(data_array, intervals)))

# True


查看完整回答
反对 回复 2021-11-09
  • 1 回答
  • 0 关注
  • 129 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信