Ответ 1
Мой обычный подход (если вы можете жить с дополнительными копиями памяти) - это делать все IO в одном процессе, а затем отправлять вещи в пул рабочих потоков. Чтобы загрузить фрагмент memmapped массива в память, просто x = np.array(data[yourslice])
(data[yourslice].copy()
на самом деле не делает этого, что может привести к некоторой путанице.).
Прежде всего, позвольте генерировать некоторые тестовые данные:
import numpy as np
np.random.random(10000).tofile('data.dat')
Вы можете воспроизвести свои ошибки примерно так:
import numpy as np
import multiprocessing
def main():
data = np.memmap('data.dat', dtype=np.float, mode='r')
pool = multiprocessing.Pool()
results = pool.imap(calculation, chunks(data))
results = np.fromiter(results, dtype=np.float)
def chunks(data, chunksize=100):
"""Overly-simple chunker..."""
intervals = range(0, data.size, chunksize) + [None]
for start, stop in zip(intervals[:-1], intervals[1:]):
yield data[start:stop]
def calculation(chunk):
"""Dummy calculation."""
return chunk.mean() - chunk.std()
if __name__ == '__main__':
main()
И если вы просто переключитесь на получение np.array(data[start:stop])
, вы устраните проблему:
import numpy as np
import multiprocessing
def main():
data = np.memmap('data.dat', dtype=np.float, mode='r')
pool = multiprocessing.Pool()
results = pool.imap(calculation, chunks(data))
results = np.fromiter(results, dtype=np.float)
def chunks(data, chunksize=100):
"""Overly-simple chunker..."""
intervals = range(0, data.size, chunksize) + [None]
for start, stop in zip(intervals[:-1], intervals[1:]):
yield np.array(data[start:stop])
def calculation(chunk):
"""Dummy calculation."""
return chunk.mean() - chunk.std()
if __name__ == '__main__':
main()
Конечно, это делает дополнительную копию в памяти каждого фрагмента.
В конечном итоге вы, вероятно, обнаружите, что проще отказаться от memmapped файлов и перейти к чему-то вроде HDF. Это особенно актуально, если ваши данные многомерны. (Я рекомендовал бы h5py
, но pyTables
приятно, если ваши данные "похожи на таблицу".)
Удачи, во всяком случае!