通过使用带有max
运算符的CUDA Thrust inclusive scan,我可以使用之前的非缺失值(即左边的最后一个非缺失值)填充缺失值。
但是如何使用下一个非缺失值填充(右侧)?因此,例如,使用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
。)
我已尝试反向进行包容性扫描,[0 6 6 6 6 6 6 6]
产生max
,而不是所需。
非常感谢。
答案 0 :(得分: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]
然后,您需要在左右两侧为特殊情况捏造物品。
答案 1 :(得分:3)
仿函数FillMissing
表示如果element为0,则将其替换为前一个元素,否则保留它。使用反向迭代器时,“previous”表示正确的迭代器。
#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