【问题标题】:Access Gadiva filter result by index in Apache Arrow通过 Apache Arrow 中的索引访问 Gadiva 过滤器结果
【发布时间】:2018-12-15 02:24:43
【问题描述】:

也许我遗漏了一些明显的东西,但在我的一生中,我无法弄清楚如何在 Gandiva 过滤器操作后访问数组的元素。

我已经链接了一个我这样编译的最小示例:

$ /usr/lib64/ccache/g++ -g -Wall -m64 -std=c++17 -pthread -fPIC \
      -I/opt/data-an/include  mwe.cc -o mwe \
      -L/opt/data-an/lib64 -lgandiva -larrow

然后我像这样运行二进制文件:

$ LD_LIBRARY_PATH=/opt/data-an/lib64 ./mwe

总的来说,这就是我正在尝试的(随后是 MWE 的摘录):

  1. 创建一个 5 元素向量:1、3、2、4、5

    int num_records = 5;
    arrow::Int64Builder i64builder;
    ArrayPtr array0;
    
    EXPECT_OK(i64builder.AppendValues({1, 3, 2, 4, 5}));
    EXPECT_OK(i64builder.Finish(&array0));
    
  2. 使用 Gandiva 获取偶数元素,索引:2、3

    // schema for input fields
    auto field0 = field("f0", arrow::int64());
    auto schema = arrow::schema({field0});
    
    // even: f0 % 2 == 0
    auto field0_node = TreeExprBuilder::MakeField(field0);
    auto lit_2 = TreeExprBuilder::MakeLiteral(int64_t(2));
    auto remainder = TreeExprBuilder::MakeFunction("mod", {field0_node, lit_2}, int64());
    auto lit_0 = TreeExprBuilder::MakeLiteral(int64_t(0));
    auto even = TreeExprBuilder::MakeFunction("equal", {remainder, lit_0}, boolean());
    auto condition = TreeExprBuilder::MakeCondition(even);
    
    // input record batch
    auto in_batch = arrow::RecordBatch::Make(schema, num_records, {array0});
    
    // filter
    std::shared_ptr<Filter> filter;
    EXPECT_OK(Filter::Make(schema, condition, &filter));
    
    std::shared_ptr<SelectionVector> selected;
    EXPECT_OK(SelectionVector::MakeInt16(num_records, pool_, &selected));
    EXPECT_OK(filter->Evaluate(*in_batch, selected));
    
  3. 使用 Gandiva 过滤器中的选择向量作为索引数组访问原始数组中的偶数元素

    // std::cout << "array0[0]: " << array0->Value(0); // doesn't compile
    // error: ‘using element_type = class arrow::Array’ {aka ‘class
    // arrow::Array’} has no member named ‘Value’
    
    // downcast it to the correct derived class
    auto array0_cast = std::dynamic_pointer_cast<NumericArray<Int64Type>>(array0);
    std::cout << "array0[0]: " << array0_cast->Value(0) << std::endl;
    

但我似乎无法访问selection vector 的元素。由于它被声明为std::shared_ptr&lt;arrow::Array&gt;,因此找不到Value(..) 方法。因为我用SelectionVector::MakeInt16(..) 填充它,所以我尝试向下转换为arrow::NumericArray&lt;Int16Type&gt;,但失败了!我不确定我哪里出错了。

auto idx_arr_cast = std::dynamic_pointer_cast<NumericArray<Int16Type>>(idx_arr);
if (idx_arr_cast) {
  std::cout << "idx_arr[0]: " << idx_arr_cast->Value(0) << std::endl;
} else {
  std::cerr << "idx_arr_cast is a nullptr!" << std::endl;
}

我还有一个相关但更笼统的问题。给定一个数组,如果我不知道确切的类型,我就找不到访问元素(或迭代它们)的方法。如果我知道类型,我可以向下转换,并使用 Value(..)GetValue(..)GetString(..) 等。这似乎很圆,只是为了访问元素。我错过了什么?

注意:完整的 MWE 以及 Makefile 可以从 this gist 克隆。

【问题讨论】:

  • 我强烈建议在 dev@ 邮件列表而不是 StackOverflow 上提出这个问题(以及未来的问题)。没有多少 Arrow 开发人员关注这里的标签。
  • 好的,谢谢。我会在开发者列表上重新发布。

标签: c++ apache-arrow


【解决方案1】:

SelectionVector 存储索引,因此类型为unsigned,如下工作:

auto arr = std::dynamic_pointer_cast<NumericArray<UInt16Type>>(selected->ToArray());

感谢 the answer 的 Arrow 开发人员名单上的 Ravindra。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-02
    • 1970-01-01
    • 2013-10-05
    • 2020-06-30
    • 1970-01-01
    • 2016-05-09
    • 1970-01-01
    相关资源
    最近更新 更多