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