用 Python 定义 Schema 并生成 Parquet 文件详情


Posted in Python onSeptember 25, 2021

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

一、简单字段定义

1、定义 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 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' )

2、验证 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 ( ) )

输出为:

 

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 ( ) )

二、含嵌套字段定义

下面的 Schema 定义加入一个嵌套对象,在 address 下分 email_address post_addressSchema 定义及生成 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 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' )

1、验证 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<email_address: string, post_address: string> , 明确的表明它是一个 struct 类型,而不是只展示嵌套层次。

到此这篇关于用 Python 定义 Schema 并生成 Parquet 文件详情的文章就介绍到这了,更多相关用 Python 定义 Schema 并生成 Parquet 文件内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
在CentOS上配置Nginx+Gunicorn+Python+Flask环境的教程
Jun 07 Python
python常用知识梳理(必看篇)
Mar 23 Python
Python3学习笔记之列表方法示例详解
Oct 06 Python
Python实现进程同步和通信的方法
Jan 02 Python
python Celery定时任务的示例
Mar 13 Python
python smtplib模块自动收发邮件功能(二)
May 22 Python
python sys.argv[]用法实例详解
May 25 Python
Python实现 版本号对比功能的实例代码
Apr 18 Python
python实现定时压缩指定文件夹发送邮件
Dec 22 Python
Tensorflow tf.dynamic_partition矩阵拆分示例(Python3)
Feb 07 Python
pymysql之cur.fetchall() 和cur.fetchone()用法详解
May 15 Python
python selenium xpath定位操作
Sep 01 Python
使用pipenv管理python虚拟环境的全过程
Sep 25 #Python
Django实现WebSocket在线聊天室功能(channels库)
Sep 25 #Python
Python天气语音播报小助手
用python基于appium模块开发一个自动收取能量的小助手
Python实现打乒乓小游戏
Python 类,对象,数据分类,函数参数传递详解
Sep 25 #Python
Python实现简单的俄罗斯方块游戏
You might like
php定义数组和使用示例(php数组的定义方法)
2014/03/29 PHP
修改yii2.0用户登录使用的user表为其它的表实现方法(推荐)
2017/08/01 PHP
Nigma vs Liquid BO3 第一场2.14
2021/03/10 DOTA
javascript:void(0)的真正含义实例分析
2008/08/20 Javascript
jQuery 学习第六课 实现一个Ajax的TreeView
2010/05/17 Javascript
很好用的js日历算法详细代码
2013/03/07 Javascript
jquery实现页面关键词高亮显示的方法
2015/03/12 Javascript
自定义百度分享的分享按钮
2015/03/18 Javascript
Nodejs的express使用教程
2015/11/23 NodeJs
AngularJS向后端ASP.NET API控制器上传文件
2016/02/03 Javascript
js实现会跳动的日历效果(完整实例)
2017/10/18 Javascript
nodejs实现爬取网站图片功能
2017/12/14 NodeJs
Node.js笔记之process模块解读
2018/05/31 Javascript
js for终止循环 跳出多层循环
2018/10/04 Javascript
微信小程序遍历Echarts图表实现多个饼图
2019/04/25 Javascript
JS数组中对象去重操作示例
2019/06/04 Javascript
react koa rematch 如何打造一套服务端渲染架子
2019/06/26 Javascript
JavaScript 正则应用详解【模式、欲查、反向引用等】
2020/05/13 Javascript
js重写alert事件(避免alert弹框标题出现网址)
2020/12/04 Javascript
代码块高亮可复制显示js插件highlight.js+clipboard.js整合
2021/02/15 Javascript
[50:12]EG vs Fnatic 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
[01:03:41]DOTA2-DPC中国联赛 正赛 Dynasty vs XG BO3 第三场 2月2日
2021/03/11 DOTA
Python ORM框架SQLAlchemy学习笔记之数据查询实例
2014/06/10 Python
Python动态生成多维数组的方法示例
2018/08/09 Python
Python使用一行代码获取上个月是几月
2018/08/30 Python
Python之qq自动发消息的示例代码
2021/02/18 Python
linux面试题参考答案(7)
2012/10/29 面试题
银行实习生自我鉴定范文
2013/09/19 职场文书
硕士研究生就业推荐信
2014/05/18 职场文书
优秀乡村医生先进事迹材料
2014/08/23 职场文书
群众路线专项整治方案
2014/10/27 职场文书
2014年残疾人工作总结
2014/12/06 职场文书
营销计划书
2015/01/17 职场文书
先进教师个人总结
2015/02/11 职场文书
工作收入证明范本
2015/06/12 职场文书
适合后台管理系统开发的12个前端框架(小结)
2021/06/29 Javascript