【问题标题】:How do I read a Parquet in R and convert it to an R DataFrame?如何在 R 中读取 Parquet 并将其转换为 R DataFrame?
【发布时间】:2015-08-04 19:18:18
【问题描述】:

我想用 R 编程语言处理 Apache Parquet 文件(在我的例子中,在 Spark 中生成)。

是否有可用的 R 阅读器?还是正在开发一个?

如果没有,到达那里最方便的方法是什么?注意:有 Java 和 C++ 绑定:https://github.com/apache/parquet-mr

【问题讨论】:

    标签: r apache-spark parquet sparkr


    【解决方案1】:

    如果您使用的是 Spark,那么现在随着 Spark 1.4 的发布而变得相对简单,请参阅下面的示例代码,该示例代码使用了现在是 Apache Spark 核心框架的一部分的 SparkR 包。

    # install the SparkR package
    devtools::install_github('apache/spark', ref='master', subdir='R/pkg')
    
    # load the SparkR package
    library('SparkR')
    
    # initialize sparkContext which starts a new Spark session
    sc <- sparkR.init(master="local")
    
    # initialize sqlContext
    sq <- sparkRSQL.init(sc)
    
    # load parquet file into a Spark data frame and coerce into R data frame
    df <- collect(parquetFile(sq, "/path/to/filename"))
    
    # terminate Spark session
    sparkR.stop()
    

    显示了一个扩展示例@ https://gist.github.com/andyjudson/6aeff07bbe7e65edc665

    如果您不使用 Spark,我不知道您可以使用任何其他软件包。

    【讨论】:

    • 您猜猜为什么这不适用于我在 S3 上的镶木地板文件?声明了密钥和秘密,python 可以使用 sqlCtx.read.parquet("s3n://bucket/path/part1=whatever/") 很好地读取它们。我也尝试将密钥和密码直接放在网址中 - “s3n://key:pass@bucket/path”
    • 恐怕我没有使用过 S3,所以我不确定什么有效或无效。可能是 SparkR 中尚不支持 S3,我们真的刚刚在核心中看到了它的第一个版本,您确实遇到了问题。您是否确认从 pyspark / scala 会话加载数据? - 如果是这样,我会更受上述理论的诱惑。可能值得检查 SparkR 问题日志 (issues.apache.org/jira/browse/SPARK/component/12325400/…) 或尝试搜索与 S3 相关的问题?
    • 尝试在文件中或启动 RStudio 时定义 AWS 环境变量:我更喜欢使用自包含脚本(第一个选项) Sys.setenv(AWS_ACCESS_KEY_ID = "") Sys.setenv(AWS_SECRET_ACCESS_KEY = "" )
    • 使用它会导致两个警告——“parquetFile(sqlContext...) 已弃用”。请改用parquetFile(...)。" --and-- "f' is deprecated. Use read.parquet` 代替。"。不幸的是,parquetFileread.parquet 中的 none 没有记录,因此不清楚正确的现在实现这个的语法
    【解决方案2】:

    您可以为此使用arrow 包。它与 Python pyarrow 中的相同,但现在它也为 R 打包,无需 Python。

    git clone https://github.com/apache/arrow.git
    cd arrow/cpp && mkdir release && cd release
    
    # It is important to statically link to boost libraries
    cmake .. -DARROW_PARQUET=ON -DCMAKE_BUILD_TYPE=Release -DARROW_BOOST_USE_SHARED:BOOL=Off
    make install
    

    然后你可以安装R arrow 包:

    devtools::install_github("apache/arrow/r")
    

    并用它来加载 Parquet 文件

    library(arrow)
    #> 
    #> Attaching package: 'arrow'
    #> The following object is masked from 'package:utils':
    #> 
    #>     timestamp
    #> The following objects are masked from 'package:base':
    #> 
    #>     array, table
    read_parquet("somefile.parquet", as_tibble = TRUE)
    #> # A tibble: 10 x 2
    #>        x       y
    #>    <int>   <dbl>
    #> …
    

    【讨论】:

    【解决方案3】:

    您可以简单地使用arrow package:

    install.packages("arrow")
    library(arrow)
    read_parquet("myfile.parquet")
    

    【讨论】:

    • @DavidArenburg 是的,虽然这个答案反映了 arrow 现在在 CRAN 上可用的变化,因此可以直接安装。
    【解决方案4】:

    除了SparkR,您现在可以使用sparklyr

    # install.packages("sparklyr")
    library(sparklyr)
    
    sc <- spark_connect(master = "local")
    
    spark_tbl_handle <- spark_read_parquet(sc, "tbl_name_in_spark", "/path/to/parquetdir")
    
    regular_df <- collect(spark_tbl_handle)
    
    spark_disconnect(sc)
    

    【讨论】:

    • 为了使用收集包 dplyr 是必需的:install.packages("dplyr")
    【解决方案5】:

    使用 reticulate,您可以使用从 python 到 parquet 文件的 pandas。这可以为您省去运行 spark 实例的麻烦。

    library(reticulate)
    library(dplyr)
    pandas <- import("pandas")
    read_parquet <- function(path, columns = NULL) {
    
      path <- path.expand(path)
      path <- normalizePath(path)
    
      if (!is.null(columns)) columns = as.list(columns)
    
      xdf <- pandas$read_parquet(path, columns = columns)
    
      xdf <- as.data.frame(xdf, stringsAsFactors = FALSE)
    
      dplyr::tbl_df(xdf)
    
    }
    
    read_parquet(PATH_TO_PARQUET_FILE)
    

    【讨论】:

    • 鉴于下面的原生 R 方法,我觉得不应该选择这个作为答案。
    • 老实说 imo:下面的答案需要 spark,这不是原生 R. CMIIW
    • IMO,这是一个有效的答案,甚至可能是有时的“最佳”答案。但是,在大多数情况下,其他解决方案之一会“更好”。
    【解决方案6】:

    Spark 已经更新,有许多新的东西和功能被弃用或重命名。

    上面安迪的回答适用于 spark v.1.4,但在 spark v.2.3 上,这是对我有用的更新。

    1. 下载最新版本的apache spark https://spark.apache.org/downloads.html(链接中的第 3 点)

    2. 解压.tgz文件。

    3. rstudio中安装devtool

      install.packages('devtools')
      
    4. 打开terminal 并按照以下步骤操作

      # This is the folder of extracted spark `.tgz` of point 1 above
      export SPARK_HOME=extracted-spark-folder-path 
      cd $SPARK_HOME/R/lib/SparkR/
      R -e "devtools::install('.')"
      
    5. 返回rstudio

      # load the SparkR package
      library(SparkR)
      
      # initialize sparkSession which starts a new Spark session
      sc <- sparkR.session(master="local")
      
      # load parquet file into a Spark data frame and coerce into R data frame
      df <- collect(read.parquet('.parquet-file-path'))
      
      # terminate Spark session
      sparkR.stop()
      

    【讨论】:

      【解决方案7】:

      miniparquet 是一个新的专用包。安装:

      devtools::install_github("hannesmuehleisen/miniparquet")
      

      来自文档的示例:

      library(miniparquet)
      
      f <- system.file("extdata/userdata1.parquet", package="miniparquet")
      df <- parquet_read(f)
      str(df)
      
      # 'data.frame': 1000 obs. of  13 variables:
      #  $ registration_dttm: POSIXct, format: "2016-02-03 07:55:29" "2016-02-03 17:04:03" "2016-02-03 01:09:31" ...
      #  $ id               : int  1 2 3 4 5 6 7 8 9 10 ...
      #  $ first_name       : chr  "Amanda" "Albert" "Evelyn" "Denise" ...
      #  $ last_name        : chr  "Jordan" "Freeman" "Morgan" "Riley" ...
      #  $ email            : chr  "ajordan0@com.com" "afreeman1@is.gd" "emorgan2@altervista.org" "driley3@gmpg.org" ...
      #  $ gender           : chr  "Female" "Male" "Female" "Female" ...
      #  $ ip_address       : chr  "1.197.201.2" "218.111.175.34" "7.161.136.94" "140.35.109.83" ...
      #  $ cc               : chr  "6759521864920116" "" "6767119071901597" "3576031598965625" ...
      #  $ country          : chr  "Indonesia" "Canada" "Russia" "China" ...
      #  $ birthdate        : chr  "3/8/1971" "1/16/1968" "2/1/1960" "4/8/1997" ...
      #  $ salary           : num  49757 150280 144973 90263 NA ...
      #  $ title            : chr  "Internal Auditor" "Accountant IV" "Structural Engineer" "Senior Cost Accountant" ...
      #  $ comments         : chr  "1E+02" "" "" "" ...
      

      【讨论】:

        【解决方案8】:

        要读取 Amazon S3 存储桶中的 parquet 文件,请尝试使用 s3a 而不是 s3n。在使用 EMR 1.4.0、RStudio 和 Spark 1.5.0 读取镶木地板文件时,这对我有用。

        【讨论】:

          【解决方案9】:

          如果您有一个多文件 parquet 文件,您可能需要执行以下操作:

          data.table::rbindlist(lapply(Sys.glob("path_to_parquet/part-*.parquet"), arrow::read_parquet))
          

          【讨论】:

          猜你喜欢
          • 2019-06-06
          • 1970-01-01
          • 2016-07-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-01-12
          • 2018-01-23
          • 1970-01-01
          相关资源
          最近更新 更多