10

在下面的示例中,我加载了一个 parquet 文件,其中包含meta字段中地图对象的嵌套记录。sparklyr似乎在处理这些方面做得很好。但是tidyr::unnest不能转换为 SQL(或 HQL - 可以理解 - 类似LATERAL VIEW explode()),因此不可用。有没有办法以其他方式取消嵌套数据?

tfl <- head(tf)
tfl
Source:   query [?? x 10]
Database: spark connection master=yarn-client app=sparklyr local=FALSE

                            trkKey             meta     sources startTime
                             <chr>           <list>      <list>    <list>
1 3juPe-k0yiMcANNMa_YiAJfJyU7WCQ3Q <S3: spark_jobj> <list [24]> <dbl [1]>
2 3juPe-k0yiAJX3ocJj1fVqru-e0syjvQ <S3: spark_jobj>  <list [1]> <dbl [1]>
3 3juPe-k0yisY7UY_ufUPUo5mE1xGfmNw <S3: spark_jobj>  <list [7]> <dbl [1]>
4 3juPe-k0yikXT5FhqNj87IwBw1Oy-6cw <S3: spark_jobj> <list [24]> <dbl [1]>
5 3juPe-k0yi4MMU63FEWYTNKxvDpYwsRw <S3: spark_jobj>  <list [7]> <dbl [1]>
6 3juPe-k0yiFBz2uPbOQqKibCFwn7Fmlw <S3: spark_jobj> <list [19]> <dbl [1]>
# ... with 6 more variables: endTime <list>, durationInMinutes <dbl>,
#   numPoints <int>, maxSpeed <dbl>, maxAltitude <dbl>, primaryKey <chr>

收集数据时也存在问题。例如,

tfl <- head(tf) %>% collect()
tfl
# A tibble: 6 × 10
                            trkKey             meta     sources startTime
                             <chr>           <list>      <list>    <list>
1 3juPe-k0yiMcANNMa_YiAJfJyU7WCQ3Q <S3: spark_jobj> <list [24]> <dbl [1]>
2 3juPe-k0yiAJX3ocJj1fVqru-e0syjvQ <S3: spark_jobj>  <list [1]> <dbl [1]>
3 3juPe-k0yisY7UY_ufUPUo5mE1xGfmNw <S3: spark_jobj>  <list [7]> <dbl [1]>
4 3juPe-k0yikXT5FhqNj87IwBw1Oy-6cw <S3: spark_jobj> <list [24]> <dbl [1]>
5 3juPe-k0yi4MMU63FEWYTNKxvDpYwsRw <S3: spark_jobj>  <list [7]> <dbl [1]>
6 3juPe-k0yiFBz2uPbOQqKibCFwn7Fmlw <S3: spark_jobj> <list [19]> <dbl [1]>
# ... with 6 more variables: endTime <list>, durationInMinutes <dbl>,
#   numPoints <int>, maxSpeed <dbl>, maxAltitude <dbl>, primaryKey <chr>

tfl %>% unnest(meta)
Error: Each column must either be a list of vectors or a list of data frames [meta]

在上面,meta文件仍然包含spark_jobj元素而不是列表、data.frames 甚至 JSON 字符串(这是 Hive 返回此类数据的方式)。这会造成tidyr甚至无法处理收集到的数据的情况。

有没有办法sparklyr更好地处理tidyr我失踪的问题?如果没有,这是否计划用于未来的sparklyr发展?

4

4 回答 4

2

这不是一个完全正确的解决方案,但是一种解决方法是使用 Hive 生成​​表或视图(例如,create view db_name.table_name as select ...)。处理爆炸操作。这为工作提供了平面数据sparklyrsc假设Hive已配置,sparklyr并且在DBI::dbGetQuery(sc, "USE db_name")列出带有src_tbls(sc). 一旦你执行dat <- tbl(sc, "table_name"),那么从那里开始应该会更顺利。

由于这不是sparklyr解决方案(而是更多的 Hive 解决方案),我不会接受这个答案。

于 2016-09-03T09:56:43.830 回答
2

我终于有了我的答案。见https://mitre.github.io/sparklyr.nested/(来源:https ://github.com/mitre/sparklyr.nested )

tf %>% 
  sdf_unnest(meta)

这对于 Spark 数据帧的行为类似于tidyr::unnest本地数据帧的行为。还实现了嵌套选择和展开操作。

更新:

因为@cem-bilge 注释explode可以在里面使用mutate。这在数组很简单(字符或数字)但在其他情况下不太重要的情况下很有效。

iris2 <- copy_to(sc, iris, name="iris")
iris_nst <- iris2 %>%
  sdf_nest(Sepal_Length, Sepal_Width, Petal.Length, Petal.Width, .key="data") %>%
  group_by(Species) %>%
  summarize(data=collect_list(data))

然后

iris_nst %>% mutate(data = explode(data)) %>% sdf_schema_viewer()

生产

在此处输入图像描述

字段仍然嵌套(尽管已爆炸),而sdf_unnest产量

iris_nst %>% sdf_unnest(data) %>% sdf_schema_viewer()

在此处输入图像描述

于 2017-08-29T00:45:29.750 回答
1

这是另一个不依赖于 Hive 的选项(至少直接LATERAL VIEW explode()是一个 Hive 的东西)。

tf %>% 
  sdf_mutate(ft_sql_transformer(
    b, paste0("SELECT trkKey, a.fld1 as fld1, a.fld2 as fld2",
              "FROM __THIS__ LATERAL VIEW explode(__THIS__.meta) x AS a")))

我也不会接受这个答案,因为我仍然希望看到类似的内容:

tf %>%
  sdf_mutate(a=ft_explode(meta))

但这需要对嵌套选择语句的支持。也许像tidyr::unnest语法这样的东西可以解决问题:

tf %>%
  sdf_mutate(a=ft_explode(meta)) %>%
  unnest(a)
于 2016-10-27T21:10:15.397 回答
0

您也可以explode()直接在 a中使用mutate()来扩展 sparklyr 中的数组。

df %>%
  mutate(my_values = explode(my_array))

注意: sparklyr.nested不是必需的。

于 2018-10-10T07:48:53.083 回答