有效的顽固的价值的分配通过布尔的面罩

0

的问题

我有一个布尔掩值的分配问题的要求有效布尔掩操作。

它是一个多层面罩和我用的 einsum 实现结果,但是操作不是很有效率,我想知道,如果我可以得到一些帮助 这是我目前的解决方案:(两个 mask, truth_value, false_value 是虚拟数据有d型和形状匹配我的问题。

mask = np.random.randn(1000, 50)> 0.5
truth_value = np.random.randn(50, 10)
false_value = np.random.randn(10)
objective = np.einsum('ij,jk->ijk', mask, truth_value) + np.einsum('ij,k->ijk', ~mask, false_value)

是否有任何快速的方式得到 objective 给予 mask, truth_value, false_value ?

而我在等待,想出了一个更快捷的方式

objective = np.where(mask[...,np.newaxis], np.broadcast_to(truth_value, (1000, 50, 10)), np.broadcast_to(false_value,  (1000, 50, 10)))

但有没有更快的替代?

mask numpy python
2021-11-21 23:00:26
1

最好的答案

0

你可以使用 ,可能还是发达国家去JIT 做到这一效率更高。

import numpy as np
import numba as nb

@nb.njit('float64[:,:,::1](bool_[:,::1], float64[:,::1], float64[::1])')
def blend(mask, truth_value, false_value):
    n, m = mask.shape
    l = false_value.shape[0]
    assert truth_value.shape == (m, l)
    result = np.empty((n, m, l), dtype=np.float64)
    for i in range(n):
        for j in range(m):
            if mask[i, j]:
                result[i, j, :] = truth_value[j, :]
            else:
                result[i, j, :] = false_value[:]
    return result

mask = np.random.randn(1000, 50) > 0.5
truth_value = np.random.randn(50, 10)
false_value = np.random.randn(10)
objective = blend(mask, truth_value, false_value)

计算 objective4.8倍的速度 在我的机器。

如果这不是足够快的,你可以尝试并行代码使用的参数 parallel=True 和使用 nb.prange 而不是的 range 在我基于循环。 这不可能以更快的速度由于开销的创建新的螺纹。 在我的机器(有6个核心),平行版本是 7.4倍的速度 (创造线是非常比较昂贵的执行时间)。

另一个可能的优化是直接写信的结果在缓冲区分配的时间提前(这仅仅是更好的如果你管这个叫功能的多次使用同一阵大小)。

这里是总体时间在我的机器:

np.einsum:         4.32 ms
np.where:          1.72 ms
numba sequential:  0.89 ms
numba parallel:    0.58 ms
2021-11-21 23:52:43

谢谢! 这确实是速度快于我的 einsum 解决方案。 一点点的速度比我的 np.where +np.broadcast_to 基于解决方案。
yupbank

其他语言

此页面有其他语言版本

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................