【问题标题】:sparklyr spark_read_parquet Reading String Fields as Listssparklyr spark_read_parquet 将字符串字段读取为列表
【发布时间】:2018-08-18 10:40:09
【问题描述】:

我有许多 parquet 格式的 Hive 文件,其中包含 stringdouble 列。我可以使用以下语法将它们中的大部分读入带有sparklyr 的 Spark 数据帧:

spark_read_parquet(sc, name = "name", path = "path", memory = FALSE)

但是,我读到了一个文件,其中所有 string 值都被转换为无法识别的列表,当收集到 R 数据框并打印时,这些列表看起来像这样:

s_df <- spark_read_parquet(sc, 
                           name = "s_df", 
                           path = "hdfs://nameservice1/user/hive/warehouse/s_df", 
                           memory = FALSE)
df <- collect(s_df)
head(df)

# A tibble: 11,081 x 13
   provid   hospital_name servcode  servcode_desc codegroup claimid  amountpaid
   <list>   <list>        <list>    <list>        <list>    <list>        <dbl>
 1 <raw [8… <raw [32]>    <raw [5]> <raw [25]>    <raw [29… <raw [1…       7.41
 2 <raw [8… <raw [32]>    <raw [5]> <raw [15]>    <raw [22… <raw [1…       4.93
 3 <raw [8… <raw [32]>    <raw [5]> <raw [28]>    <raw [22… <raw [1…       5.36
 4 <raw [8… <raw [32]>    <raw [5]> <raw [28]>    <raw [30… <raw [1…       5.46
 5 <raw [8… <raw [32]>    <raw [5]> <raw [16]>    <raw [30… <raw [1…       2.80 

df 前 5 行的 hospital_name 应为 METHODIST HOSPITAL OF SOUTHERN CALIFORNIA,但改为这样显示:

head(df$hospital_name)

[[1]]
 [1] 48 45 4e 52 59 20 4d 41 59 4f 20 4e 45 57 48 41 4c 4c 20 4d 45 4d 4f 52 49
[26] 41 4c 20 48 4f 53 50

[[2]]
 [1] 48 45 4e 52 59 20 4d 41 59 4f 20 4e 45 57 48 41 4c 4c 20 4d 45 4d 4f 52 49
[26] 41 4c 20 48 4f 53 50

[[3]]
 [1] 48 45 4e 52 59 20 4d 41 59 4f 20 4e 45 57 48 41 4c 4c 20 4d 45 4d 4f 52 49
[26] 41 4c 20 48 4f 53 50

[[4]]
 [1] 48 45 4e 52 59 20 4d 41 59 4f 20 4e 45 57 48 41 4c 4c 20 4d 45 4d 4f 52 49
[26] 41 4c 20 48 4f 53 50

[[5]]
 [1] 48 45 4e 52 59 20 4d 41 59 4f 20 4e 45 57 48 41 4c 4c 20 4d 45 4d 4f 52 49
[26] 41 4c 20 48 4f 53 50

我尝试了以下解决方案,但没有成功:

head(df %>% mutate(hospital_name = as.character(hospital_name)))

[1] "as.raw(c(0x48, 0x45, 0x4e, 0x52, 0x59, 0x20, 0x4d, 0x41, 0x59, 0x4f, 0x20, 0x4e, 0x45, 0x57, 0x48, 0x41, 0x4c, 0x4c, 0x20, 0x4d, 0x45, 0x4d, 0x4f, 0x52, 0x49, 0x41, 0x4c, 0x20, 0x48, 0x4f, 0x53, 0x50))"
[2] "as.raw(c(0x48, 0x45, 0x4e, 0x52, 0x59, 0x20, 0x4d, 0x41, 0x59, 0x4f, 0x20, 0x4e, 0x45, 0x57, 0x48, 0x41, 0x4c, 0x4c, 0x20, 0x4d, 0x45, 0x4d, 0x4f, 0x52, 0x49, 0x41, 0x4c, 0x20, 0x48, 0x4f, 0x53, 0x50))"
[3] "as.raw(c(0x48, 0x45, 0x4e, 0x52, 0x59, 0x20, 0x4d, 0x41, 0x59, 0x4f, 0x20, 0x4e, 0x45, 0x57, 0x48, 0x41, 0x4c, 0x4c, 0x20, 0x4d, 0x45, 0x4d, 0x4f, 0x52, 0x49, 0x41, 0x4c, 0x20, 0x48, 0x4f, 0x53, 0x50))"
[4] "as.raw(c(0x48, 0x45, 0x4e, 0x52, 0x59, 0x20, 0x4d, 0x41, 0x59, 0x4f, 0x20, 0x4e, 0x45, 0x57, 0x48, 0x41, 0x4c, 0x4c, 0x20, 0x4d, 0x45, 0x4d, 0x4f, 0x52, 0x49, 0x41, 0x4c, 0x20, 0x48, 0x4f, 0x53, 0x50))"
[5] "as.raw(c(0x48, 0x45, 0x4e, 0x52, 0x59, 0x20, 0x4d, 0x41, 0x59, 0x4f, 0x20, 0x4e, 0x45, 0x57, 0x48, 0x41, 0x4c, 0x4c, 0x20, 0x4d, 0x45, 0x4d, 0x4f, 0x52, 0x49, 0x41, 0x4c, 0x20, 0x48, 0x4f, 0x53, 0x50))"

感谢您在解决问题方面提供的任何帮助,或提出任何建议以使我的请求更加明确。谢谢。

【问题讨论】:

  • 这看起来像是字符串编码问题。您是否能够使用其他工具(例如 parquet-tools)读取此特定文件?

标签: r hive spark-dataframe parquet sparklyr


【解决方案1】:

reprex 会很好(仅适用于 df),例如使用dput(head(df)) 并将结果粘贴到此处。 请尝试以下操作:

df %>% mutate(hospital_name = unlist(lapply(hospital_name, function(e) rawToChar(e))))

【讨论】:

    【解决方案2】:

    在读取 parquet 文件之前为 Spark Session 配置设置 spark.sql.parquet.binaryAsString 属性的问题:

    sc$config$spark.sql.parquet.binaryAsString = TRUE
    

    备注:在我的情况下,事实证明,由于在 IMPALA 中插入而创建的镶木地板文件包含描述为“二进制”而不是“二进制 UTF8”的“字符字段”。在这种情况下,另一种解决方案是在插入数据之前在 impala-shell 中设置PARQUET_ANNOTATE_STRINGS_UTF8

    > set PARQUET_ANNOTATE_STRINGS_UTF8=1;
    PARQUET_ANNOTATE_STRINGS_UTF8 set to 1
    

    【讨论】:

      猜你喜欢
      • 2020-03-24
      • 2018-08-28
      • 2019-08-18
      • 2018-03-09
      • 2013-02-13
      • 1970-01-01
      • 1970-01-01
      • 2021-08-26
      相关资源
      最近更新 更多