【问题标题】:Get schema of parquet file in Python在 Python 中获取镶木地板文件的模式
【发布时间】:2017-05-24 20:08:41
【问题描述】:

是否有任何 python 库可用于获取 parquet 文件的架构?

目前我们正在将 parquet 文件加载到 Spark 中的数据框中,并从数据框中获取模式以显示在应用程序的某些 UI 中。但是初始化 spark-context 和加载数据框并从数据框获取模式是耗时的活动。所以寻找一种替代方法来获取架构。

【问题讨论】:

  • 文件是否在 HDFS 中?
  • Spark 不需要加载整个数据集来获取架构。从 parquet 文件中获取模式应该是即时的。
  • @Thiago Baldim - 是的,它仅在 HDFS 中

标签: python parquet


【解决方案1】:

此函数返回表示 parquet 文件的本地 URI 的架构。模式作为可用的 Pandas 数据框返回。该函数不读取整个文件,只读取架构。

import pandas as pd
import pyarrow.parquet


def read_parquet_schema_df(uri: str) -> pd.DataFrame:
    """Return a Pandas dataframe corresponding to the schema of a local URI of a parquet file.

    The returned dataframe has the columns: column, pa_dtype
    """
    # Ref: https://stackoverflow.com/a/64288036/
    schema = pyarrow.parquet.read_schema(uri, memory_map=True)
    schema = pd.DataFrame(({"column": name, "pa_dtype": str(pa_dtype)} for name, pa_dtype in zip(schema.names, schema.types)))
    schema = schema.reindex(columns=["column", "pa_dtype"], fill_value=pd.NA)  # Ensures columns in case the parquet file has an empty dataframe.
    return schema

已使用以下版本的第三方包进行测试:

$ pip list | egrep 'pandas|pyarrow'
pandas             1.1.3
pyarrow            1.0.1

【讨论】:

    【解决方案2】:

    这通过使用pyarrow (https://github.com/apache/arrow/) 得到支持。

    from pyarrow.parquet import ParquetFile
    # Source is either the filename or an Arrow file handle (which could be on HDFS)
    ParquetFile(source).metadata
    

    注意:我们昨天才合并了这个代码,所以你需要从源代码构建它,见https://github.com/apache/arrow/commit/f44b6a3b91a15461804dd7877840a557caa52e4e

    【讨论】:

    • 谢谢。看起来构建 travis-ci.org/apache/arrow/jobs/190525227 状态为绿色。你能告诉我从哪里得到构建吗?否则你能指出我如何构建这个箭头的文档吗?
    • 这可行,但不能将响应作为字典或数组而不是普通文本返回吗?
    【解决方案3】:

    除了@mehdio 的回答,如果您的 parquet 是一个目录(例如 spark 生成的 parquet),请读取架构/列名:

    import pyarrow.parquet as pq
    pfile = pq.read_table("file.parquet")
    print("Column names: {}".format(pfile.column_names))
    print("Schema: {}".format(pfile.schema))
    

    【讨论】:

    • 如果文件太大而无法读入内存怎么办?
    【解决方案4】:

    read_schema 方法现在有一个最简单的方法。请注意,它实际上返回一个字典,其中您的架构是字节文字,因此您需要一个额外的步骤来将架构转换为正确的 python 字典。

    from pyarrow.parquet import read_schema
    import json
    
    schema = read_schema(source)
    schema_dict = json.loads(schema.metadata[b'org.apache.spark.sql.parquet.row.metadata'])['fields']
    

    【讨论】:

    • 这可以使用 AWS s3 作为源吗?除了使用ParquetDataset 读取它然后访问schema 属性之外,我无法让它工作
    • 是的,我实际上是在 s3 中使用它。通过 io 使用缓冲区,参见示例 stackoverflow.com/a/51027520/12076032
    • 这需要将数据读入内存虽然正确吗?我试图简单地从 s3 中的对象的镶木地板文件中获取模式并比较它们
    • 是的,正确。那么你有2个选择。 1)要么选择一个不应该很大(几兆)的镶木地板文件,这没关系 2)或者您将数据公开为 Athena 表,您可以使用 boto3 来获取架构。
    • 不适用于spark生成的parquet:错误信息为ArrowIOError: Cannot open for reading: path 'file.parquet' is a directory
    【解决方案5】:

    正如其他评论者所提到的,PyArrow 是使用 Python 获取 Parquet 文件模式的最简单方法。我的回答更详细地介绍了 PyArrow 返回的架构和存储在 Parquet 文件中的元数据。

    import pyarrow.parquet as pq
    
    table = pq.read_table(path)
    table.schema # returns the schema
    

    以下是创建 PyArrow 架构的方法(这是 table.schema 返回的对象):

    import pyarrow as pa
    
    pa.schema([
        pa.field("id", pa.int64(), True),
        pa.field("last_name", pa.string(), True),
        pa.field("position", pa.string(), True)])
    

    每个 PyArrow 字段都有 nametypenullablemetadata 属性。有关如何使用 PyArrow 将自定义文件/列元数据写入 Parquet 文件的更多详细信息,请参阅here

    type 属性用于 PyArrow DataType 对象。 pa.int64()pa.string() 是 PyArrow 数据类型的示例。

    确保您了解column level metadata,例如最小值/最大值。这将帮助您了解 Parquet 文件允许在大数据系统中使用的一些很酷的功能,例如谓词下推过滤。

    【讨论】:

    • @Asclepius - 谓词下推可通过查询优化器在 Spark 中使用,而不是来自惰性求值。
    • 为什么 PyArrow 中的谓词下推不像 SQL 中那样自动?
    猜你喜欢
    • 2021-01-12
    • 2021-02-19
    • 1970-01-01
    • 2015-06-21
    • 2022-11-24
    • 1970-01-01
    • 2019-08-04
    • 2022-06-16
    • 2018-12-01
    相关资源
    最近更新 更多