Python: передача массива memmap через функцию?
Предположим, что я работаю с очень большим массивом (например, ~45 ГБ) и пытаюсь передать его через функцию, которая открывает принимает массивные массивы. Каков наилучший способ:
- Сохранить это для ограниченной памяти?
- Передать этот сохраненный массив в функцию, которая принимает только пустые массивы?
1 ответ
TLDR; просто попробуйте...
Я ничего не знаю о скрытых марковских моделях, но что касается numpy mmap, вы можете найти, что это просто сработает. Я говорю это, потому что np.memmap
является прямым подклассом ndarray
, Тем не менее, даже в документации говорится, что он "не совсем подходит подклассу ndarray" и предполагает, что можно создать объект mmap самостоятельно mmap.mmap(...)
, ИМАО, посмотрев на numpy.memmap.__new__()
функция, вы не могли бы сделать больше, чтобы сделать ее заменой, в этом случае вам придется взглянуть на функции, которые вы хотите использовать, и почему массивы mmap не воспроизводятся хорошо. Если это произойдет, может быть даже проще изменить эти файлы, чем изменить способ применения mmap.
И последнее замечание: при работе непосредственно с диска (даже с буферизацией) будьте готовы к некоторым медленным вычислениям... Я бы предложил найти соответствующий исходный код и взломать указатель хода выполнения для вычислительно дорогих разделов. Кроме того, инкрементная обратная запись может спасти вас от повторного вычисления больших разделов данных в случае ошибки (или просто отключения питания).
Вот пример того, как я мог бы добавить отчеты о прогрессе в GaussianHMM().fit()
:
дополнения выделены жирным шрифтом
изменения в hmmlearn\base.py
:
class _BaseHMM(BaseEstimator):
# ...
def fit(self, X, lengths=None):
# ...
for iter in range(self.n_iter):
stats = self._initialize_sufficient_statistics()
curr_logprob = 0
for i, j in iter_from_X_lengths(X, lengths, iter, self.n_iter): # tell our generator which iteration
# ...
pass
изменения в hmmlearn\utils.py
def iter_from_X_lengths(X, lengths, iteration, stop):
if lengths is None:
yield 0, len(X)
print("completion: 100%")
else:
length = len(lengths) #used every loop so I copied it to a local var
n_samples = X.shape[0]
end = np.cumsum(lengths).astype(np.int32)
start = end - lengths
if end[-1] > n_samples:
raise ValueError("more than {0:d} samples in lengths array {1!s}"
.format(n_samples, lengths))
for i in range(length):
yield start[i], end[i]
# convert loop iterations to % completion
print("completion: {}%".format(int((float(iteration)/stop)+(float(i)/length/stop))*100))