我需要从自定义二进制文件中读取大量数据(使用多处理和随机访问),以便执行计算并存储到镶木地板数据集。 我知道列数,但不知道要存储的项目数。
因此,文件被切割成 N
逻辑部分,每个部分都由块读取器功能处理。
所以我应该进入这些功能:
x
创建List
列(通过追加动态分配)并在块的末尾创建一个记录批次?y
记录创建一个记录批次。这里我们按批次控制物品的数量。这个过程可能会更慢,因为我们必须在每次迭代中放置一个条件 (if no_items == y:…
)RecordBatchStreamWriter
中以返回缓冲区RecordBatchStreamWriter
中以返回缓冲区我阅读了 ipc、memory、arrow-streaming-columnar,但仍然不清楚如何处理巨大的随机访问文件。
感谢您的见解
答案 0 :(得分:2)
如果您想要的输出是拼花数据集,而您的输入格式是自定义二进制文件,那么记录批处理 API 可能不会帮助您,除非您将计算分布在多个进程(而不是线程)中。您提到了多处理,因此可能是这种情况,但我只是想确保您不是指多线程。
另外,当你说一个镶木地板数据集时,我不确定你是说一个巨大的镶木地板文件,还是你说的是公共目录结构中的一定数量的镶木地板文件。通常一个“镶木地板数据集”是多个镶木地板文件。
此任务具有很大的灵活性,因此您如何进行可能取决于您以后希望如何读取数据。
多个文件。您创建多个镶木地板文件,其中每个镶木地板文件包含数据的所有列,但仅包含 X 行。如果您可以在数据中的某些列上对批次进行分区(例如测量日期/制造日期/设备 ID/实验标准),那么您将能够非常有效地将这些用作以后的查询参数(例如,如果您稍后按测量日期查询,您可以通过文件名和目录名找出要加载的文件)。在这种情况下,您将需要 dataset APIs。您也可以始终使用这种方法按行号进行分区,尽管您希望在那种情况下比单个文件情况具有同样多的优势(使用仅支持整个文件镶木地板读取的 3rd 方镶木地板工具仍然会更容易)。< /p>
单个文件。您可以创建一个巨大的单个镶木地板文件,该文件被分成许多“行组”。这将允许您稍后读取单个行组,或者通过一次处理单个行组来执行内存高效的批处理。这里的缺点是您只能按“行号”进行批处理,因此如果您以后想通过诸如时间戳列之类的内容进行查找,那么您可能必须读取/扫描所有数据(除非您知道某种映射方式)行号的时间戳)。如果您想要这种方法,您将需要使用 ParquetWriter 来编写单独的行组。
在写入上述任何内容之前,您需要以自定义格式读取并将数据转换为 Arrow 格式。如果您纯粹在 python 中执行此操作,这可能会很昂贵,但由于它是自定义格式,因此您不太可能使用内置的 Arrow 实用程序来读取数据。如果您的自定义格式具有任何类型的用于读取数据的本机库,那么使用这些库读取数据、提取相关数据缓冲区并用箭头元数据包装它们以便箭头可以访问它们可能会更快。使用 python 操作生成的 Arrow 元数据对象(例如表/分块数组等)应该非常简单/快速。
如果您选择在 python 中解析文件,那么它的成本可能会非常大,以至于您选择哪个选项 1-4 并不重要。理想情况下,您希望能够将输入文件读入您打算写入的块中。希望从输入文件中读取固定大小的一批行(所有列)会很容易。
如果您希望您的输出格式按一列或多列进行分区(例如按测试条件分区),那么它会更复杂。如果没有好的方法知道测试标准如何映射到行,您可能必须将整个文件作为单个表读入内存,进行多次传递,或者拥有多个文件(例如,您可以拥有多个文件而不是每个测试标准一个文件)每个测试标准 20 个,只需将输入文件读取为 20 个批次)。
既然你提到了多处理和记录批读取器/写入器,我将稍微谈谈如何使用它们。如果您决定跨多个进程(甚至可能是多个服务器)读取您的文件,并且您希望这些进程进行通信,那么您可以使用记录批处理读取器/写入器。例如,假设您有一个完全致力于读取自定义文件并将其解析为箭头格式的进程。然后,该进程可以使用记录批写入器将这些文件发送到下一个进程,该进程将使用记录批读取器读取它们。例如,第二个进程可以执行将该记录批量写入一定数量的镶木地板文件的工作。记录批量读写器允许你以箭头格式写入,以便进程间快速传输。
如果不了解您正在阅读的文件以及您的最终处理/查询目标,就很难确切地说出该做什么。我认为对您的问题的简单回答是,您阅读输入的方式将取决于您最终希望如何创建输出。