用Python读取和写入Parquet文件

这篇文章主要介绍如何在Python中写入和读取parquet文件。这些类型的文件是一种存储系统格式,以列的方式存储数据。

与CSV等基于行的文件格式相比,Parquet是一种性能优化的文件格式。在你的基于Parquet的文件系统上执行查询时,可以非常迅速地将重点放在所需的数据上。

在Python中读取和写入Parquet文件的Parquet接口

Python 使用引擎在数据框上写入数据并读取 Parquet 文件。这篇文章将解释一些在数据库上写入parquet文件的引擎。

为了在数据分析系统中使用,Apache Parquet 项目提供了一种标准化的开源列存储格式。对于从Parquet文件中读取或写入的数据,Apache Arrow是最好的内存传输层。

我们将学习两个在Python中读取parquet文件的parquet接口:pyarrowfastparquet

Python中的PyArrow模块

Apache Arrow或PyArrow是一个内存分析开发平台。它有一个技术集合,让大数据系统快速存储、处理和传输数据。

这段代码在pyarrow ,使其可以使用Pandas写和读parquet文件。

使用pipconda ,安装pyarrow 很容易。

对于pip ,使用这个命令:

pip install pyarrow

对于conda ,使用这个命令:

conda install -c conda-forge pyarrow

使用PyArrow模块在Python中向Parquet文件写入数据帧

为了了解如何在Python中写入数据帧和读取parquet文件,让我们在下面的程序中创建一个Pandas表。

需要有四个导入:

  1. pyarrow – 用于编写parquet产品。
  2. numpy – 用于多维数组。
  3. pandas – 用于创建数据框架。
  4. parquetpyarrow 的一个子函数。

这个程序创建了一个数据框架store1 ,其中有多种类型的数据集,如整数、字符串和布尔值。索引列表被设置为'abc' ,以按字母顺序排列行。

在一个变量table1 ,使用语法Table.from_pandas() ,创建一个潘达斯表。这个表被打印出来以检查结果。

import pyarrow.parquet as pq
import numpy as np
import pandas as pd
import pyarrow as pa
store1 = pd.DataFrame({'first': [5, np.nan, -9],
                       'second': ['apple', 'samsung', 'mi'],
                       'third': [False, False, True]},
                      index=list('abc'))
table1 = pa.Table.from_pandas(store1)
print(table1)

输出:

C:python38python.exe "C:/Users/Win 10/main.py"
pyarrow.Table
first: double
second: string
third: bool
__index_level_0__: string
----
first: [[5,null,-9]]
second: [["apple","samsung","mi"]]
third: [[false,false,true]]
__index_level_0__: [["a","b","c"]]
Process finished with exit code 0

现在,这些数据被写成parquet格式,write_table 。当写一个parquet文件时,write_table() 函数包括几个参数来控制不同的设置。

  1. data_page_size – 这个参数规定了一个列块中的编码数据页的大致数量。目前,1MB是默认值。
  2. flavor – 这提供了特定于Apache Spark Parquet消费者的兼容性设置,如spark
  3. version – 这是适当的Parquet格式版本。1.0 和更高的值保证了与早期阅读器的兼容性,而2.4 和更高的值则可以实现更多的Parquet类型和编码。

在这个程序中,write_table() 参数提供了表table1 和一个用于写入 Parquet 的本地文件parquet.txt

文件的来源可以不使用字符串来表示。以下任何一种方式都是可能的:

  • 一个作为字符串的文件路径
  • 一个本地的PyArrow 文件
  • 一个Python中的文件对象

为了读取这个表,使用了read_table() 函数。一个变量table2 ,用来将表加载到它上面。

最后,使用table2.to_pandas() 将这个parquet文件转换为Pandas数据框架,并打印出来。

pq.write_table(table1, 'sample_file.parquet')
table2 = pq.read_table('sample_file.parquet')
table2.to_pandas()
print("n", table2)

输出:

C:python38python.exe "C:/Users/Win 10/main.py"
 pyarrow.Table
first: double
second: string
third: bool
__index_level_0__: string
----
first: [[5,null,-9]]
second: [["apple","samsung","mi"]]
third: [[false,false,true]]
__index_level_0__: [["a","b","c"]]
Process finished with exit code 0

Parquet文件通常是巨大的数据文件,在Python中读取parquet文件需要很长的时间来加载。所以,可以通过特定的列来快速读取数据,而不是加载整个文件:

在变量table3 中,pq.read_table 函数被用来写入数据。在参数括号内,提供了两个列:firstthird

table3 = pq.read_table('parquet.txt', columns=['first', 'third'])
print(table3)

输出将显示选定的列。

输出:

C:python38python.exe "C:/Users/Win 10/main.py"
pyarrow.Table
first: double
third: bool
----
first: [[5,null,-9]]
third: [[false,false,true]]
Process finished with exit code 0

我们使用read_pandas ,以潘达斯数据框架为源,从文件中读取一个子集的列时,保留任何额外的索引列数据:

table4 = pq.read_pandas('parquet.txt', columns=['second']).to_pandas()
print(table4)

输出:

C:python38python.exe "C:/Users/Win 10/main.py"
       second
a    apple
b  samsung
c       mi
Process finished with exit code 0

一个字符串文件路径或一个NativeFile (特别是内存映射)的实例在读取时将比Python文件对象表现得更好,后者的读取速度通常最差。

当使用pa.Table.from_pandas 将一个表转换为Arrow表时,会自动创建一个或多个特殊列,以保持对索引(行标签)的跟踪。如果索引没有价值,可以通过preserve index=False ,选择省略,因为存储索引需要更多的存储空间。

import numpy as np
import pandas as pd
import pyarrow as pa
import pyarrow.parquet as pq
store = pd.DataFrame({'first': [5, np.nan, -9],
                      'second': ['apple', 'samsung', 'mi'],
                      'third': [False, False, True]},
                     index=list('abc'))
print(store)
table = pa.Table.from_pandas(store, preserve_index=False)
pq.write_table(table, 'sample_file.parquet')
t = pq.read_table('sample_file.parquet')
print("n", t.to_pandas())

显示的parquet文件的索引被擦除。

输出:

C:python38python.exe "C:/Users/Win 10/main.py"
   first   second  third
a    5.0    apple  False
b    NaN  samsung  False
c   -9.0       mi   True
    first   second  third
0    5.0    apple  False
1    NaN  samsung  False
2   -9.0       mi   True
Process finished with exit code 0

使用PyArrow模块在Python中读取Parquet文件的元数据

除了从文件中读取数据外,read_table 方法使用的ParquetFile 类还提供了额外的功能,如读取元数据。

import pyarrow.parquet as pq
parquet_file = pq.ParquetFile('example.parquet')
print(parquet_file.metadata)

输出:

C:python38python.exe "C:/Users/Win 10/main.py"
<pyarrow._parquet.FileMetaData object at 0x000001DADCBDCA90>
  created_by: parquet-cpp-arrow version 9.0.0
  num_columns: 4
  num_rows: 3
  num_row_groups: 1
  format_version: 2.6
  serialized_size: 2580
Process finished with exit code 0

使用Python中的Fastparquet引擎向Parquet文件写入数据

这是一个用于parquet文件格式的Python接口。

这个程序使用fastparquet ,在parquet文件上进行写入。创建了一个有两列的数据框storestudentmarks

使用dataframe.to_parquet() 函数将该数据框写入parquet文件sample.parquet

引擎被选择为fastparquet ,但也可以设置为pyarrow

import pandas as pd
store = pd.DataFrame({
    'student': ['Michael', 'Jackson', 'N', 'John', 'Cena'],
    'marks': [20, 10, 22, 21, 22],
})
print(store)
store.to_parquet('sample.parquet', engine='fastparquet')

输出:

C:python38python.exe "C:/Users/Win 10/main.py"
   student  marks
0  Michael     20
1  Jackson     10
2        N     22
3     John     21
4     Cena     22
Process finished with exit code 0

由于数据被写入了parquet文件,我们来读一下这个文件。

在Python中使用Fastparquet引擎读取parquet文件

使用pd.read_parquet 函数读取parquet文件,将引擎设置为fastparquet ,并将其存储在一个变量df 内。然后将结果打印出来。

df = pd.read_parquet('sample.parquet', engine='fastparquet')
print(df)

输出:

C:python38python.exe "C:/Users/Win 10/PycharmProjects/read_parquet/main.py"
   student  marks
0  Michael     20
1  Jackson     10
2        N     22
3     John     21
4     Cena     22
Process finished with exit code 0

结论

这篇文章解释了如何在Python中读取parquet文件。程序实例演示了使用pyarrowfastparquet 读取 parquet 文件。

读者应该能够轻松地创建在Python中读取parquet文件的程序。