【问题标题】:How does Spark DataFrame handles Pandas DataFrame that is larger than memorySpark DataFrame如何处理大于内存的Pandas DataFrame
【发布时间】:2016-01-29 21:51:57
【问题描述】:

我现在正在学习Spark,它似乎是Pandas Dataframe的大数据解决方案,但是我有这个问题让我不确定。

目前我正在使用 HDF5 存储大于内存的 Pandas 数据帧。 HDF5 是一个很棒的工具,它允许我对 pandas 数据帧进行分块。因此,当我需要对大型 Pandas 数据帧进行处理时,我会分块进行。但 Pandas 不支持分布式处理,HDF5 仅适用于单机环境。

使用 Spark 数据帧可能是解决方案,但我对 Spark 的理解是数据帧必须能够放入内存中,并且一旦作为 Spark 数据帧加载,Spark 会将数据帧分发给不同的工作人员进行分布式处理。

我的理解正确吗?如果是这种情况,那么 Spark 如何处理大于内存的数据帧?是否支持分块,如 HDF5?

【问题讨论】:

    标签: pandas apache-spark dataframe apache-spark-sql hdf5


    【解决方案1】:

    数据帧必须能够放入内存,并且一旦作为 Spark 数据帧加载,Spark 会将数据帧分发给不同的工作人员进行分布式处理。

    仅当您尝试将数据加载到驱动程序上然后进行并行化时才适用。在典型情况下,您以可以并行读取的格式存储数据。这意味着您的数据:

    • 必须在每个工作人员上都可以访问,例如使用分布式文件系统
    • 文件格式必须支持拆分(最简单的例子是普通的旧 csv)

    在这种情况下,每个工作人员只读取自己的数据集部分,而无需将数据存储在驱动程序内存中。所有与计算拆分相关的逻辑都由适用的 Hadoop 输入格式透明地处理。

    关于 HDF5 文件,您有两种选择:

    • 在驱动程序上以块的形式读取数据,从每个块构建 Spark DataFrame,并合并结果。这是低效的,但很容易实现
    • 分发 HDF5 文件/文件并直接在工作人员上读取数据。一般来说,这很难实现,需要智能的数据分发策略

    【讨论】:

    • 假设我有一个无法放入内存的大型数据框,在磁盘上采用镶木地板格式。我在本地运行火花。 spark如何在分区中加载这个数据帧?它是自动分区数据帧并进行处理(例如计算数据帧每一列的值出现),还是我必须手动将此数据帧分成块并将它们存储在镶木地板中,然后调用火花,告诉它在哪里存储的块,并进行处理?
    • 关于第一个问题,它通常使用适用的 Hadoop 输入格式在内部处理。我不确定我是否理解第二个问题。如果数据已经存储在 Parquet 中,那么除了确保它确实适合内存之外,别无他法。如果要将 HDF5 转换为 parquet,则必须手动分区。
    • 让我重新定义第二个问题,因为我一直在阅读 spark 文档。让我们假设我们有一个集群,我有一个无法放入任何节点内存的原始数据。以下用于加载和处理文件的管道对您有意义吗? csv 中的原始数据 -> 在驱动程序中将原始数据并行化为 rdd -> 在驱动程序中将 rdd 转换为 spark 数据帧 -> 进行必要的数据处理 -> 将 spark 数据帧存储到 parquet。对于最后一步,数据仍然大于内存,但其分区存储在不同的节点中,由 spark 确定。
    • 不,它没有并使用spark-csv(或SparkContext.textFile,但我不建议这样做)阅读。
    • 感谢您的建议。在驱动程序加载原始数据的主要原因是允许 spark 使用 spark 的独立集群管理器将数据并行化到 rdd,假设集群可以支持 rdd 而不会内存崩溃。您是否建议使用以下管道:csv 中的原始数据 -> 使用 spark-csv 加载原始数据以在驱动程序处触发数据帧 -> 进行必要的数据处理 -> 将火花数据帧存储到镶木地板。
    猜你喜欢
    • 1970-01-01
    • 2016-02-10
    • 2016-09-26
    • 2019-09-18
    • 2021-06-13
    • 2019-07-08
    • 2017-03-17
    • 1970-01-01
    相关资源
    最近更新 更多