使用Python以多线程顺序读取和写入核心文件

使用Python以多线程顺序读取和写入核心文件,python,numpy,dask,python-xarray,joblib,Python,Numpy,Dask,Python Xarray,Joblib,总体目标:我想在不适合内存的数据集上训练pytorch模型 现在忘了我提到过pytorch,它归结为:从核心或内存映射中读写一个大文件 我找到了很多库,但是我找不到一个能让我进行多线程顺序读写的库。我想做的是让多个线程附加到文件/数据帧(顺序不重要,应该为下游应用程序洗牌)。然后当读取时,我只需要顺序读取(没有切片,没有索引),但同样多个线程应该能够被馈送 我发现/想出了以下解决方案: csv:这不是一个选项,因为存储浮点数会导致精度损失(处理编码和转义也很可怕) :您需要提前知道数组的大小,

总体目标:我想在不适合内存的数据集上训练pytorch模型

现在忘了我提到过pytorch,它归结为:从核心或内存映射中读写一个大文件

我找到了很多库,但是我找不到一个能让我进行多线程顺序读写的库。我想做的是让多个线程附加到文件/数据帧(顺序不重要,应该为下游应用程序洗牌)。然后当读取时,我只需要顺序读取(没有切片,没有索引),但同样多个线程应该能够被馈送

我发现/想出了以下解决方案:

  • csv
    :这不是一个选项,因为存储浮点数会导致精度损失(处理编码和转义也很可怕)
  • :您需要提前知道数组的大小,无论是读还是写,追加似乎都很重要
  • :我找不到附加到数据帧的方法,它在附加时总是创建一个新的数据帧,而且新的数据帧似乎没有文件备份。这看起来很适合阅读,但是创建一个新的核心外数据帧并没有文档记录
  • :同样,没有关于如何写入文件支持的数据帧的文档,而是说明了
    ,需要注意的是,当您修改数据集的值时,即使是链接到磁盘上文件的数据集,只有您在xarray中操作的内存中的副本被修改:磁盘上的原始文件从未被触及。
    所以这似乎不可能
  • :相同的故事,阅读是,重复写作否
  • :也没有行追加
  • :无行追加。为什么?
它们都支持核心外读取,这很好,但我需要先将其转换为特定的文件格式(写入)——我缺少什么


看起来多线程写入是一个难题。但即使是单线程增量写入,但多线程读取也已经很好了,但似乎没有库支持这一点?

多线程顺序写入可能容易出错。大多数系统通常更喜欢像拼花这样的格式,允许他们将每个数据块写入不同的文件


如果您想执行实际的并行顺序写入,您必须执行某种类型的锁定,对于更大的一体式系统,您可能需要自己解决。

我终于找到了一个可行的解决方案

增量写入:

import pyarrow as pa

result = []
writer = False
for _, row in df.iterrows():
  result.append(process_row(row))
  if len(result) >= 10000:
    batch = pa.RecordBatch.from_pandas(pd.DataFrame(result))
    if not writer:
      writer = pa.RecordBatchFileWriter(f'filename.arrow', batch.schema)
      writer.write(batch)
      result = []
batch = pa.RecordBatch.from_pandas(pd.DataFrame(result))
writer.write(batch)
writer.close()
将所有数据读入一个数据帧:

pa.RecordBatchFileReader("filename.arrow").read_pandas()
增量读取:

rb = pa.RecordBatchFileReader("filename.arrow")
for i in range(rb.num_record_batches):
  b = rb.get_batch(i)

好吧,多线程写入会很好。但似乎没有一个简单的核心外多线程读取。从Dask或Spark这样的库读取/到拼花地板有什么问题吗?他们都很乐意并行地读写拼花地板数据。好吧,请参阅我在上面对dask的评论“我找不到一种附加到数据帧的方法,它总是在附加时创建一个新的数据帧,而且新的数据帧似乎没有文件备份。这看起来很适合阅读,但创建一个新的核心外数据帧没有文档记录。”我找不到顺序写入dask DataFrame的方法您发布的增量写入示例似乎不是多线程写入(除非我遗漏了什么?)。您是否能够将其调整为多线程?尽管我相信在2020年应该可以编写多线程(我们在90年代有具有该功能的数据库?),但似乎任何库都不可能进行多线程编写。至少我们可以进行多线程阅读——但是,是的,所有这些库都有很大的改进空间。