1

通过将 CUDA Thrust 的包含性扫描max运算符一起使用,我能够用前一个非缺失值(即左侧的最后一个非缺失值)填充缺失值。

但是如何使用下一个非缺失值(右侧)填充?因此,例如,0用作我的缺失值标记:

                  Input: [0 1 0 0 4 0 6 0]
 Fill missing from left: [0 1 1 1 4 4 6 6]
Fill missing from right: [0 1 4 4 4 6 6 6]   <- want

(请注意,如果最后一个元素丢失,则恢复为0从左侧填充 final s。)

我尝试了反向的包容性扫描,它产生[0 6 6 6 6 6 6 6]了 for max,而不是预期的结果。

非常感谢。

4

2 回答 2

3

max()从左到右扫描时对升序值起作用的原因是当前最大值将始终高于您的0缺失元素,因此它成为填充缺失元素的正确值,即使它有一个“记忆”来所有从一开始的方式。

如果您只是从右到左扫描,max()则不再有效,因为您有一个递减范围。

因此,您似乎需要使用rbegin()rend()从右到左扫描,此外,使用 MAX_INT 作为占位符和min()运算符。

Input: [MAX_INT 1 MAX_INT MAX_INT 4 MAX_INT 6 MAX_INT]
Fill missing from right: [1 1 4 4 4 6 6 MAX_INT]

然后,您需要在左右两侧为您的特殊情况捏造一些东西。

于 2013-01-14T00:53:19.020 回答
3

函子FillMissing表示如果元素为0,则将其替换为前一个元素,否则保留它。使用反向迭代器时,“前一个”表示正确的迭代器。

#include <thrust/device_vector.h>
#include <thrust/scan.h>
#include <iterator>

template<class T>
struct FillMissing
{
    __host__ __device__ T operator()(const T& res, const T& dat)
    {
        return dat == T(0) ? res : dat;
    }
};

int main()
{
    thrust::device_vector<double> vec(8);
    vec[1] = 1;
    vec[4] = 4;
    vec[6] = 6;

    thrust::inclusive_scan(
            vec.rbegin(), vec.rend(),
            vec.rbegin(),
            FillMissing<double>());

    thrust::copy(
            vec.begin(), vec.end(),
            std::ostream_iterator<double>(std::cout, " "));
    std::cout << std::endl;
}

输出。

1 1 4 4 4 6 6 0

您可能需要额外的代码来处理尾随的 0

于 2013-01-14T02:29:17.227 回答