我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Golang如何处理parquet文件

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Golang如何处理parquet文件

这篇文章主要介绍“Golang如何处理parquet文件”,在日常操作中,相信很多人在Golang如何处理parquet文件问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Golang如何处理parquet文件”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

前言

Parquet是Apache基金会支持的项目,是面向列存储二进制文件格式。支持不同类型的压缩方式,广泛用于数据科学和大数据环境,如Hadoop生态。

创建结构体

首先创建struct,用于表示要处理的数据:

type user struct {  ID        string    `parquet:"name=id, type=BYTE_ARRAY, encoding=PLAIN_DICTIONARY"`  FirstName string    `parquet:"name=firstname, type=BYTE_ARRAY, encoding=PLAIN_DICTIONARY"`  LastName  string    `parquet:"name=lastname, type=BYTE_ARRAY, encoding=PLAIN_DICTIONARY"`  Email     string    `parquet:"name=email, type=BYTE_ARRAY, encoding=PLAIN_DICTIONARY"`  Phone     string    `parquet:"name=phone, type=BYTE_ARRAY, encoding=PLAIN_DICTIONARY"`  Blog      string    `parquet:"name=blog, type=BYTE_ARRAY, encoding=PLAIN_DICTIONARY"`  Username  string    `parquet:"name=username, type=BYTE_ARRAY, encoding=PLAIN_DICTIONARY"`  Score     float64   `parquet:"name=score, type=DOUBLE"`  CreatedAt time.Time //wont be saved in the parquet file}

这里要提醒的是tag,用于说明struct中每个字段在生成parquet过程中如何被处理。

parquet-go包可以处理parquet数据,更多的tag可以参考其官网。

生成parquet文件

下面现给出生成parquet文件的代码,然后分别进行说明:

package mainimport (  "fmt"  "log"  "time"  "github.com/bxcodec/faker/v3"  "github.com/xitongsys/parquet-go-source/local"  "github.com/xitongsys/parquet-go/parquet"  "github.com/xitongsys/parquet-go/reader"  "github.com/xitongsys/parquet-go/writer")type user struct {  ID        string    `parquet:"name=id, type=BYTE_ARRAY, encoding=PLAIN_DICTIONARY"`  FirstName string    `parquet:"name=firstname, type=BYTE_ARRAY, encoding=PLAIN_DICTIONARY"`  LastName  string    `parquet:"name=lastname, type=BYTE_ARRAY, encoding=PLAIN_DICTIONARY"`  Email     string    `parquet:"name=email, type=BYTE_ARRAY, encoding=PLAIN_DICTIONARY"`  Phone     string    `parquet:"name=phone, type=BYTE_ARRAY, encoding=PLAIN_DICTIONARY"`  Blog      string    `parquet:"name=blog, type=BYTE_ARRAY, encoding=PLAIN_DICTIONARY"`  Username  string    `parquet:"name=username, type=BYTE_ARRAY, encoding=PLAIN_DICTIONARY"`  Score     float64   `parquet:"name=score, type=DOUBLE"`  CreatedAt time.Time //wont be saved in the parquet file}const recordNumber = 10000func main() {  var data []*user  //create fake data  for i := 0; i < recordNumber; i++ {    u := &user{      ID:        faker.UUIDDigit(),      FirstName: faker.FirstName(),      LastName:  faker.LastName(),      Email:     faker.Email(),      Phone:     faker.Phonenumber(),      Blog:      faker.URL(),      Username:  faker.Username(),      Score:     float64(i),      CreatedAt: time.Now(),    }    data = append(data, u)  }  err := generateParquet(data)  if err != nil {    log.Fatal(err)  }}func generateParquet(data []*user) error {  log.Println("generating parquet file")  fw, err := local.NewLocalFileWriter("output.parquet")  if err != nil {    return err  }  //parameters: writer, type of struct, size  pw, err := writer.NewParquetWriter(fw, new(user), int64(len(data)))  if err != nil {    return err  }  //compression type  pw.CompressionType = parquet.CompressionCodec_GZIP  defer fw.Close()  for _, d := range data {    if err = pw.Write(d); err != nil {      return err    }  }  if err = pw.WriteStop(); err != nil {    return err  }  return nil}

定义结构体上面已经说明,但需要提醒的是类型与文档保持一致:

Primitive TypeGo Type
BOOLEANbool
INT32int32
INT64int64
INT96(deprecated)string
FLOATfloat32
DOUBLEfloat64
BYTE_ARRAYstring
FIXED_LEN_BYTE_ARRAYstring

接着就是使用faker包生成模拟数据。然后调用err := generateParquet(data)方法。该方法大概逻辑为:

  • 首先准备输出文件,然后基于本地输出文件构造pw,用于写parquet数据:

  fw, err := local.NewLocalFileWriter("output.parquet")  if err != nil {    return err  }  //parameters: writer, type of struct, size  pw, err := writer.NewParquetWriter(fw, new(user), int64(len(data)))  if err != nil {    return err  }  //compression type  pw.CompressionType = parquet.CompressionCodec_GZIP  defer fw.Close()

然后设置压缩类型,并通过defer操作确保关闭文件。下面开始写数据:

  for _, d := range data {    if err = pw.Write(d); err != nil {      return err    }  }  if err = pw.WriteStop(); err != nil {    return err  }  return nil

循环写数据,最后调用pw.WriteStop()停止写。 成功写文件后,下面介绍如何读取parquet文件。

读取parquet文件

首先介绍如何一次性读取文件,主要用于读取较小的文件:

func readParquet() ([]*user, error) {  fr, err := local.NewLocalFileReader("output.parquet")  if err != nil {    return nil, err  }  pr, err := reader.NewParquetReader(fr, new(user), recordNumber)  if err != nil {    return nil, err  }  u := make([]*user, recordNumber)  if err = pr.Read(&u); err != nil {    return nil, err  }  pr.ReadStop()  fr.Close()  return u, nil}

大概流程如下:首先定义本地文件,然后构造pr用于读取parquet文件:

  fr, err := local.NewLocalFileReader("output.parquet")  if err != nil {    return nil, err  }  pr, err := reader.NewParquetReader(fr, new(user), recordNumber)  if err != nil {    return nil, err  }

然后定义目标内容容器u,一次性读取数据:

  u := make([]*user, recordNumber)  if err = pr.Read(&u); err != nil {    return nil, err  }  pr.ReadStop()  fr.Close()

但一次性大量记录加载至内存可能有问题。这是官方文档提示:

If the parquet file is very big (even the size of parquet file is small, the uncompressed size may be very large), please don&rsquo;t read all rows at one time, which may induce the OOM. You can read a small portion of the data at a time like a stream-oriented file.

大意是不要一次读取文件至内存,可能造成OOM。实际应用中应该分页读取,下面通过代码进行说明:

func readPartialParquet(pageSize, page int) ([]*user, error) {fr, err := local.NewLocalFileReader("output.parquet")if err != nil {return nil, err}defer func() {_ = fr.Close()}()pr, err := reader.NewParquetReader(fr, new(user), int64(pageSize))if err != nil {return nil, err}defer pr.ReadStop()//num := pr.GetNumRows()pr.SkipRows(int64(pageSize * page))u := make([]*user, pageSize)if err = pr.Read(&u); err != nil {return nil, err}return u, nil}

与上面函数差异不大,首先函数包括两个参数,用于指定页大小和页数,关键代码是跳过一定记录:

  pr.SkipRows(int64(pageSize * page))

根据这个方法可以获得总行数,pr.GetNumRows(),然后结合页大小计算总页数,最后循环可以实现分页查询。

计算列平均值

既然使用了Parquet列存储格式,下面演示下如何计算Score列的平均值。

func calcScoreAVG() (float64, error) {  fr, err := local.NewLocalFileReader("output.parquet")  if err != nil {    return 0.0, err  }  pr, err := reader.NewParquetColumnReader(fr, recordNumber)  if err != nil {    return 0.0, err  }  num := int(pr.GetNumRows())  data, _, _, err := pr.ReadColumnByPath("parquet_go_root\u0001score", num)  if err != nil {    return 0.0, err  }  var result float64  for _, i := range data {    result += i.(float64)  }  return (result / float64(num)), nil}

首先打开文件,然后调用pr.GetNumRows()方法获取总行数。然后基于路径指定列,其中parquet_go_root为根路径,因为前面使用字节数组,这里分割符变为\u0001,完整路径为:parquet_go_root\u0001score

到此,关于“Golang如何处理parquet文件”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Golang如何处理parquet文件

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Golang如何处理parquet文件

这篇文章主要介绍“Golang如何处理parquet文件”,在日常操作中,相信很多人在Golang如何处理parquet文件问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Golang如何处理parquet文件
2023-07-05

Golang处理parquet文件实战指南

这篇文章主要给大家介绍了关于Golang处理parquet文件的相关资料,文中通过实例代码介绍的非常详细,对大家学习或者使用Golang具有一定的参考学习价值,需要的朋友可以参考下
2023-03-07

Golang文件处理:如何正确关闭文件

Golang文件处理:如何正确关闭文件在使用Golang编程时,处理文件是一个常见的操作。然而,有些开发者在处理完文件后忽略了正确关闭文件的操作,这可能会导致资源泄露和程序性能下降。因此,本文将介绍如何正确关闭文件,并提供具体的代码示例,
Golang文件处理:如何正确关闭文件
2024-02-28

golang如何高效处理大文件

这篇文章主要介绍了golang如何高效处理大文件,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。使用Pandas分块处理大文件问题:今天在处理快手的用户数据时,遇到了一个差不多
2023-06-15

R语言中如何读取Parquet文件

在R语言中,可以使用arrow包来读取Parquet文件。首先需要安装arrow包,然后使用arrow::read_parquet()函数来读取Parquet文件。以下是一个示例代码:# 安装arrow包install.package
R语言中如何读取Parquet文件
2024-04-08

Golang 上传文件时如何处理临时文件?

在 golang 中处理上传文件的临时文件,涉及的步骤包括:接收上传的文件。创建临时文件。上传文件到临时文件。验证文件类型(可选)。处理完成或上传失败时,删除临时文件。Golang 上传文件时处理临时文件在 Golang 中处理临时文件对
Golang 上传文件时如何处理临时文件?
2024-05-13

Golang 文件上传中如何处理空文件名?

针对 go 文件上传中的空文件名,需采取以下步骤:检查 formfile 对象是否存在,若为空返回错误。创建自定义解析器,检查上传文件名称是否为空,若为空返回错误。Golang 文件上传中处理空文件名的指南在 Go 语言中处理文件上传时,
Golang 文件上传中如何处理空文件名?
2024-05-13

一文详解如何使用Golang处理文件

Golang是一种强类型、静态编译、并发性高的编程语言,我们将重点介绍Golang中的文件基本操作,包括创建文件与查看状态,重命名与移动,删除与截断,读写文件,以及权限控制,跟着小编一起来学习吧
2023-05-17

如何在 Golang 中处理文件读写错误?

在 go 中处理文件读写错误的关键步骤如下:使用 os.open 打开文件,并将错误分配给 err 变量。检查 err 是否非空以检测错误。使用多种方法处理错误,例如打印、记录或使用 errors 包的内置类型。在实战案例中,readfil
如何在 Golang 中处理文件读写错误?
2024-05-15

Golang 中如何处理多部分文件上传?

在 golang 中处理多部分文件上传涉及:使用 multipart/form-data 内容类型划分请求为多个部分。使用 formfile 和 parsemultipartform 函数解析请求。获取上传的文件并进行处理。实战案例:在 h
Golang 中如何处理多部分文件上传?
2024-05-13

如何在 Golang 中处理文件系统错误?

在 go 中处理文件系统错误至关重要,可以使用错误类型(如 errnotexist)和错误处理技术(如多重返回值、errors 包)来实现。使用错误类型可以明确错误原因,使用错误处理技术可以根据错误类型采取适当措施,从而确保程序稳定和健壮。
如何在 Golang 中处理文件系统错误?
2024-05-15

Golang 文件上传中如何处理不同编码的文件名?

在 go 文件上传中处理不同编码的文件名,可以使用以下两种解决方法:使用 mime.header 和 url 解码。mime.header 通过 filename 字段存储原始编码,而 url 解码使用 pathunescape 函数来解析
Golang 文件上传中如何处理不同编码的文件名?
2024-05-13

Golang 文件上传中如何处理并发上传?

并发文件上传涉及对上传请求实施并发限制、使用队列管理上传顺序、处理异常情况等步骤。在 golang 中,可通过以下方式实现:设置并发上限,避免资源耗尽。使用队列管理待处理请求,确保公平性和顺序性。处理上传过程中可能发生的异常情况,例如文件损
Golang 文件上传中如何处理并发上传?
2024-05-14

将 parquet 文件转换为带有嵌套元素的 Golang 结构

php小编新一将介绍如何将 parquet 文件转换为带有嵌套元素的 Golang 结构。Parquet 是一种高效的列式存储格式,而 Golang 是一种强大的编程语言,将它们结合起来可以帮助我们更好地处理和分析大量的数据。通过使用适当的
将 parquet 文件转换为带有嵌套元素的 Golang 结构
2024-02-10

如何处理Linux文件

小编给大家分享一下如何处理Linux文件,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Linux 提供了多种用于处理文件的命令,这些命令可以节省你的时间,并使你的
2023-06-16

如何在 Golang 中高效地处理大量文件读写?

如何高效处理文件读写?并发 io:利用协程并行处理文件块,提升效率。内存映射:将文件映射到进程内存,消除系统调用和文件系统操作开销。如何在 Golang 中高效地处理大量文件读写?在 Golang 项目中处理大量文件读写时,优化性能至关重
如何在 Golang 中高效地处理大量文件读写?
2024-05-16

python如何处理json文件

在Python中,可以使用`json`模块来处理JSON文件。具体步骤如下:1. 导入`json`模块:`import json`2. 读取JSON文件:可以使用`open()`函数打开JSON文件,并使用`json.load()`方法加载
2023-09-22

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录