使用Python顺序多线程读取和写入核心文件
Reading and writing out of core files sequentially multi-threaded with Python
总体目标:我想在不适合内存的数据集上训练一个pytorch模型。
现在忘记我谈到了 pytorch,它归结为:从核心或内存映射中读取和写入大文件。
我找到了很多库,但找不到一个可以让我进行多线程顺序读写的库。我想要做的是让多个线程附加到 file/dataframe(顺序无关紧要,无论如何都应该为下游应用程序洗牌)。然后在阅读时我只需要顺序阅读(没有切片,没有索引),但同样应该能够提供多个线程。
我found/came想出了以下解决方案:
csv
:不是一个选项,因为存储浮点数会导致精度损失(处理编码和转义也很糟糕)
numpy.memmep
: 你需要提前知道数组的大小,无论是读写,追加似乎都不简单。
dask
:我找不到附加到数据框的方法,它总是在附加时创建一个新数据框,而且新数据框似乎没有文件支持。这看起来很适合阅读,但没有记录创建新的核心数据框。
xarray
:同样没有关于如何写入文件支持的数据框的文档,而是文档指出 It is important to note that when you modify values of a Dataset, even one linked to files on disk, only the in-memory copy you are manipulating in xarray is modified: the original file on disk is never touched.
所以这似乎不可能?
joblib
:同一个故事,阅读有,迭代写作没有
blaze
:也没有行追加
vaex
:没有追加行。为什么‽
很高兴他们都支持非核心阅读,但我需要先以特定的文件格式获取它(写作)——我在这里错过了什么?
看来多线程写是个难题。不过单线程增量写就算了,多线程读就已经不错了,但是好像没有库支持?
多线程顺序写入很容易出错。大多数系统通常更喜欢像 Parquet 这样的格式,这种格式允许它们将每个数据块写入不同的文件。
如果您想进行实际的并行顺序写入,则必须进行某种锁定,并且就更大的一体化系统而言,您可能只能靠自己了。
我终于找到了 pyarrow 的有效解决方案。
增量写入:
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)
总体目标:我想在不适合内存的数据集上训练一个pytorch模型。
现在忘记我谈到了 pytorch,它归结为:从核心或内存映射中读取和写入大文件。
我找到了很多库,但找不到一个可以让我进行多线程顺序读写的库。我想要做的是让多个线程附加到 file/dataframe(顺序无关紧要,无论如何都应该为下游应用程序洗牌)。然后在阅读时我只需要顺序阅读(没有切片,没有索引),但同样应该能够提供多个线程。
我found/came想出了以下解决方案:
csv
:不是一个选项,因为存储浮点数会导致精度损失(处理编码和转义也很糟糕)numpy.memmep
: 你需要提前知道数组的大小,无论是读写,追加似乎都不简单。dask
:我找不到附加到数据框的方法,它总是在附加时创建一个新数据框,而且新数据框似乎没有文件支持。这看起来很适合阅读,但没有记录创建新的核心数据框。xarray
:同样没有关于如何写入文件支持的数据框的文档,而是文档指出It is important to note that when you modify values of a Dataset, even one linked to files on disk, only the in-memory copy you are manipulating in xarray is modified: the original file on disk is never touched.
所以这似乎不可能?joblib
:同一个故事,阅读有,迭代写作没有blaze
:也没有行追加vaex
:没有追加行。为什么‽
很高兴他们都支持非核心阅读,但我需要先以特定的文件格式获取它(写作)——我在这里错过了什么?
看来多线程写是个难题。不过单线程增量写就算了,多线程读就已经不错了,但是好像没有库支持?
多线程顺序写入很容易出错。大多数系统通常更喜欢像 Parquet 这样的格式,这种格式允许它们将每个数据块写入不同的文件。
如果您想进行实际的并行顺序写入,则必须进行某种锁定,并且就更大的一体化系统而言,您可能只能靠自己了。
我终于找到了 pyarrow 的有效解决方案。
增量写入:
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)