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

作者:Yanbin Blog 时间:2021-09-24 14:14:18 

目录
  • 一、简单字段定义

    • 1、定义 Schema 并生成 Parquet 文件

    • 2、验证 Parquet 数据文件

  • 二、含嵌套字段定义

    • 1、验证 Parquet 数据文件

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 类型,而不是只展示嵌套层次。

来源:https://www.tuicool.com/articles/mEfMZrM

标签:Python,Schema,Parquet,文件
0
投稿

猜你喜欢

  • seo网站如何实现301跳转?

    2010-01-15 12:59:00
  • 常见数据库系统比较 Oracle数据库

    2010-07-28 12:44:00
  • ASP.NET MVC Bundles 用法和说明(打包javascript和css)

    2023-07-17 01:20:59
  • python基础入门学习笔记(Python环境搭建)

    2022-01-12 20:27:48
  • 浅析网页Transitional和Strict的文档声明的区别

    2009-02-17 12:45:00
  • Python中22个万用公式的小结

    2022-12-15 21:06:38
  • PHP禁止页面缓存的代码

    2023-07-04 05:35:02
  • js金额浮点格式化控件

    2008-08-01 16:52:00
  • python语言线程标准库threading.local解读总结

    2023-12-22 18:18:07
  • 如何应对SQL Server数据库崩溃

    2008-11-24 17:25:00
  • 认清区别CSS的类class和id

    2007-10-08 12:02:00
  • 探究Python中isalnum()方法的使用

    2021-12-05 19:05:31
  • MYSQL教程:查询优化之有效加载数据

    2009-02-27 15:45:00
  • 如何在Python中将字符串转换为数组详解

    2021-09-10 06:36:09
  • python中尾递归用法实例详解

    2023-10-09 06:46:15
  • Django contenttypes 框架详解(小结)

    2023-11-13 14:39:47
  • python实现人机对战的五子棋游戏

    2021-07-05 04:36:03
  • Elasticsearch属性单词常用解析说明

    2023-06-12 14:47:36
  • Golang依赖注入工具digo的使用详解

    2023-08-27 13:00:43
  • python中读入二维csv格式的表格方法详解(以元组/列表形式表示)

    2023-04-19 06:39:39
  • asp之家 网络编程 m.aspxhome.com