热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

用Python定义Schema并生成Parquet文件

原来用Java和Python实现过Avro转换成Parquet格式,所以Schema都是在Avro中定义的。这里要尝试的是如何定义Parquet的Schema,然后据

  原来用 Java 和 Python 实现过 Avro 转换成 Parquet 格式,所以 Schema 都是在 Avro 中定义的。这里要尝试的是如何定义 Parquet 的 Schema, 然后据此填充数据并生成 Parquet 文件。

  本文将演示两个例子,一个是没有层级的两个字段,另一个是含于嵌套级别的字段,将要使用到的 Python 模块有 pandas 和 pyarrow

简单字段定义


定义 Schema 并生成 Parquet 文件

import pandas as pd
import pyarrow as pa
import pyarrow.parquet as pq# 定义 Schema
schema = pa.schema([('id', pa.int32()),('email', pa.string())
])# 准备数据
ids = pa.array([1, 2], type = pa.int32())
emails = pa.array(['first@example.com', 'second@example.com'], pa.string())# 生成 Parquet 数据
batch = pa.RecordBatch.from_arrays([ids, emails],schema = schema
)
table = pa.Table.from_batches([batch])# 写 Parquet 文件 plain.parquet
pq.write_table(table, 'plain.parquet')
import pandas as pdimport pyarrow as paimport pyarrow . parquet as pq# 定义 Schemaschema = pa . schema ( [( 'id' , pa . int32 ( ) ) ,( 'email' , pa . string ( ) )] )# 准备数据ids = pa . array ( [ 1 , 2 ] , type = pa . int32 ( ) )emails = pa . array ( [ 'first@example.com' , 'second@example.com' ] , pa . string ( ) )# 生成 Parquet 数据batch = pa . RecordBatch . from_arrays ([ ids , emails ] ,schema = schema)table = pa . Table . from_batches ( [ batch ] )

写 Parquet 文件 plain.parquet

pq . write_table ( table , ‘plain.parquet’ )

验证 Parquet 数据文件

我们可以用工具 parquet-tools 来查看 plain.parquet 文件的数据和 Schema

$ parquet-tools schema plain.parquet message schema { optional int32 id; optional binary email (STRING); } $ parquet-tools cat --json plain.parquet {"id":1,"email":"first@example.com"} {"id":2,"email":"second@example.com"}

没问题,与我们期望的一致。也可以用 pyarrow 代码来获取其中的 Schema 和数据

schema = pq.read_schema('plain.parquet')
print(schema)df = pd.read_parquet('plain.parquet')
print(df.to_json())
schema = pq . read_schema ( 'plain.parquet' )print ( schema )df = pd . read_parquet ( 'plain.parquet' )print ( df . to_json ( ) )

输出为

id: int32-- field metadata --PARQUET:field_id: '1'
email: string-- field metadata --PARQUET:field_id: '2'
{"id":{"0":1,"1":2},"email":{"0":"first@example.com","1":"second@example.com"}}
id : int32-- field metadata --PARQUET : field_id : '1'email : string-- field metadata --PARQUET : field_id : '2'{ "id" : { "0" : 1 , "1" : 2 } , "email" : { "0" : "first@example.com" , "1" : "second@example.com" } }

含嵌套字段定义

下面的 Schema 定义加入一个嵌套对象,在 address 下分 email_address 和 post_address,Schema 定义及生成 Parquet 文件的代码如下

import pandas as pd
import pyarrow as pa
import pyarrow.parquet as pq# 内部字段
address_fields = [('email_address', pa.string()),('post_address', pa.string()),
]# 定义 Parquet Schema,address 嵌套了 address_fields
schema = pa.schema(j)# 准备数据
ids = pa.array([1, 2], type = pa.int32())
addresses = pa.array([('first@example.com', 'city1'), ('second@example.com', 'city2')],pa.struct(address_fields)
)# 生成 Parquet 数据
batch = pa.RecordBatch.from_arrays([ids, addresses],schema = schema
)
table = pa.Table.from_batches([batch])# 写 Parquet 数据到文件
pq.write_table(table, 'nested.parquet')
import pandas as pdimport pyarrow as paimport pyarrow . parquet as pq# 内部字段address_fields = [( 'email_address' , pa . string ( ) ) ,( 'post_address' , pa . string ( ) ) ,]# 定义 Parquet Schema,address 嵌套了 address_fieldsschema = pa . schema ( j )# 准备数据ids = pa . array ( [ 1 , 2 ] , type = pa . int32 ( ) )addresses = pa . array ([ ( 'first@example.com' , 'city1' ) , ( 'second@example.com' , 'city2' ) ] ,pa . struct ( address_fields ))# 生成 Parquet 数据batch = pa . RecordBatch . from_arrays ([ ids , addresses ] ,schema = schema)table = pa . Table . from_batches ( [ batch ] )# 写 Parquet 数据到文件pq . write_table ( table , 'nested.parquet' )

验证 Parquet 数据文件

同样用 parquet-tools 来查看下 nested.parquet 文件

$ parquet-tools schema nested.parquet message schema { optional int32 id; optional group address { optional binary email_address (STRING); optional binary post_address (STRING); } } $ parquet-tools cat --json nested.parquet {"id":1,"address":{"email_address":"first@example.com","post_address":"city1"}} {"id":2,"address":{"email_address":"second@example.com","post_address":"city2"}}

parquet-tools 看到的 Schama 并没有 struct 的字样,但体现了它 address 与下级属性的嵌套关系。

用 pyarrow 代码来读取 nested.parquet 文件的 Schema 和数据是什么样子

schema = pq.read_schema("nested.parquet")
print(schema)df = pd.read_parquet('nested.parquet')
print(df.to_json())
schema = pq . read_schema ( "nested.parquet" )print ( schema )df = pd . read_parquet ( 'nested.parquet' )print ( df . to_json ( ) )

id: int32-- field metadata --PARQUET:field_id: '1'
address: struct<email_address: string, post_address: string>child 0, email_address: string-- field metadata --PARQUET:field_id: '3'child 1, post_address: string-- field metadata --PARQUET:field_id: '4'-- field metadata --PARQUET:field_id: '2'
{"id":{"0":1,"1":2},"address":{"0":{"email_address":"first@example.com","post_address":"city1"},"1":{"email_address":"second@example.com","post_address":"city2"}}}id : int32-- field metadata --PARQUET : field_id : '1'address : struct & lt ; email_address : string , post_address : string & gt ;child 0 , email_address : string-- field metadata --PARQUET : field_id : '3'child 1 , post_address : string-- field metadata --PARQUET : field_id : '4'-- field metadata --PARQUET : field_id : '2'{ "id" : { "0" : 1 , "1" : 2 } , "address" : { "0" : { "email_address" : "first@example.com" , "post_address" : "city1" } , "1" : { "email_address" : "second@example.com" , "post_address" : "city2" } } }

数据当然是一样的,有略微不同的是显示的 Schema 中, address 标识为 struct , 明确的表明它是一个 struct 类型,而不是只展示嵌套层次。

最后留下一个问题,前面我们定义 Parquet Schema 都是在 Python 代码中完成了,Parquet 是否也能像 Avro 一样用外部文件来定义 Schema, 然后编译给 Python 用?
在这里插入图片描述
   如果对软件测试、接口测试、自动化测试、持续集成、面试经验。感兴趣可以进到806549072,群内会有不定期的分享测试资料。还会有技术大牛,业内同行一起交流技术


推荐阅读
  • 使用 ListView 浏览安卓系统中的回收站文件 ... [详细]
  • 如何精通编程语言:全面指南与实用技巧
    如何精通编程语言:全面指南与实用技巧 ... [详细]
  • 优化后的标题:深入探讨网关安全:将微服务升级为OAuth2资源服务器的最佳实践
    本文深入探讨了如何将微服务升级为OAuth2资源服务器,以订单服务为例,详细介绍了在POM文件中添加 `spring-cloud-starter-oauth2` 依赖,并配置Spring Security以实现对微服务的保护。通过这一过程,不仅增强了系统的安全性,还提高了资源访问的可控性和灵活性。文章还讨论了最佳实践,包括如何配置OAuth2客户端和资源服务器,以及如何处理常见的安全问题和错误。 ... [详细]
  • 深入理解Java中的多态性概念及其应用
    多态是面向对象编程中的三大核心特性之一,与封装和继承共同构成了面向对象的基础。多态使得代码更加灵活和可扩展,封装和继承则为其提供了必要的支持。本文将深入探讨多态的概念及其在Java中的具体应用,帮助读者全面理解和掌握这一关键知识点。 ... [详细]
  • 本文探讨了资源访问的学习路径与方法,旨在帮助学习者更高效地获取和利用各类资源。通过分析不同资源的特点和应用场景,提出了多种实用的学习策略和技术手段,为学习者提供了系统的指导和建议。 ... [详细]
  • 本文探讨了利用Java实现WebSocket实时消息推送技术的方法。与传统的轮询、长连接或短连接等方案相比,WebSocket提供了一种更为高效和低延迟的双向通信机制。通过建立持久连接,服务器能够主动向客户端推送数据,从而实现真正的实时消息传递。此外,本文还介绍了WebSocket在实际应用中的优势和应用场景,并提供了详细的实现步骤和技术细节。 ... [详细]
  • 掌握Android UI设计:利用ZoomControls实现图片缩放功能
    本文介绍了如何在Android应用中通过使用ZoomControls组件来实现图片的缩放功能。ZoomControls提供了一种简单且直观的方式,让用户可以通过点击放大和缩小按钮来调整图片的显示大小。文章详细讲解了ZoomControls的基本用法、布局设置以及与ImageView的结合使用方法,适合初学者快速掌握Android UI设计中的这一重要功能。 ... [详细]
  • 本文作为“实现简易版Spring系列”的第五篇,继前文深入探讨了Spring框架的核心技术之一——控制反转(IoC)之后,将重点转向另一个关键技术——面向切面编程(AOP)。对于使用Spring框架进行开发的开发者来说,AOP是一个不可或缺的概念。了解AOP的背景及其基本原理,对于掌握这一技术至关重要。本文将通过具体示例,详细解析AOP的实现机制,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 在C#编程中,数值结果的格式化展示是提高代码可读性和用户体验的重要手段。本文探讨了多种格式化方法和技巧,如使用格式说明符、自定义格式字符串等,以实现对数值结果的精确控制。通过实例演示,展示了如何灵活运用这些技术来满足不同的展示需求。 ... [详细]
  • 线程能否先以安全方式获取对象,再进行非安全发布? ... [详细]
  • 手指触控|Android电容屏幕驱动调试指南
    手指触控|Android电容屏幕驱动调试指南 ... [详细]
  • 本文介绍了如何在iOS平台上使用GLSL着色器将YV12格式的视频帧数据转换为RGB格式,并展示了转换后的图像效果。通过详细的技术实现步骤和代码示例,读者可以轻松掌握这一过程,适用于需要进行视频处理的应用开发。 ... [详细]
  • 在处理遗留数据库的映射时,反向工程是一个重要的初始步骤。由于实体模式已经在数据库系统中存在,Hibernate 提供了自动化工具来简化这一过程,帮助开发人员快速生成持久化类和映射文件。通过反向工程,可以显著提高开发效率并减少手动配置的错误。此外,该工具还支持对现有数据库结构进行分析,自动生成符合 Hibernate 规范的配置文件,从而加速项目的启动和开发周期。 ... [详细]
  • Spring框架中的面向切面编程(AOP)技术详解
    面向切面编程(AOP)是Spring框架中的关键技术之一,它通过将横切关注点从业务逻辑中分离出来,实现了代码的模块化和重用。AOP的核心思想是将程序运行过程中需要多次处理的功能(如日志记录、事务管理等)封装成独立的模块,即切面,并在特定的连接点(如方法调用)动态地应用这些切面。这种方式不仅提高了代码的可维护性和可读性,还简化了业务逻辑的实现。Spring AOP利用代理机制,在不修改原有代码的基础上,实现了对目标对象的增强。 ... [详细]
  • 技术分享:深入解析GestureDetector手势识别机制
    技术分享:深入解析GestureDetector手势识别机制 ... [详细]
author-avatar
mobiledu2502885927
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有