Python:通过函数传递memmap数组?

时间:2016-10-27 18:05:40

标签: python numpy numpy-memmap

假设我正在处理非常大的数组(例如,~45GB)并且我试图通过一个打开接受numpy数组的函数传递它。最好的方法是:

  1. 存储此内存有限吗?
  2. 将此存储的数组传递给只接受numpy数组的函数?

1 个答案:

答案 0 :(得分:1)

TLDR;试试吧......

我对隐藏的马尔可夫模型一无所知,但对于numpy mmap,你可能会发现它只是工作。我这样说是因为np.memmapndarray的直接子类。也就是说,即使在documentation中,也表示它“不太适合ndarray子类”,并建议可以使用mmap.mmap(...)自己创建mmap对象。 IMAO在查看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))