gpt4 book ai didi

python - 对 Memmapped 数组进行操作的正确方法

转载 作者:太空狗 更新时间:2023-10-30 00:14:29 26 4
gpt4 key购买 nike

我感到困惑的操作看起来像这样。我一直在常规 Numpy 数组上这样做,但在 memmap 上我想了解它是如何工作的。

arr2 = np.argsort(np.argsort(arr1,axis=0),axis=0) / float(len(arr1)) * 100
#This is basically to calculate Percentile rank of each value wrt the entire column

这是我在普通 numpy 数组上使用的。

现在。考虑到 arr1 现在是一个 20GB 内存映射数组,我有几个问题:

1:

arr2 = np.argsort(np.argsort(arr1,axis=0),axis=0) / float(len(arr1)) * 100 

arr2 将是一个常规的 numpy 数组,我假设?所以执行这将是灾难性的内存明智的,对吧?

考虑到我现在已经将 arr2 创建为大小正确的 Memmapped 数组(全为零)。

2:

arr2 = np.argsort(np.argsort(arr1,axis=0),axis=0) / float(len(arr1)) * 100

对比

arr2[:] = np.argsort(np.argsort(arr1,axis=0),axis=0) / float(len(arr1)) * 100

有什么区别?

3.

单独计算np.argsort作为临时内存映射数组和np.argsort(np.argsort)作为临时内存映射数组然后做手术?因为 20GB 数组的 argsort 数组本身就非常庞大!

我认为这些问题将帮助我弄清楚 python 中内存映射数组的内部工作原理!

谢谢...

最佳答案

我将尝试先回答第 2 部分,然后是第 1 部分和第 3 部分。

首先,arr = <something>是简单的变量赋值,而 arr[:] = <something>分配给数组的内容。在下面的代码中,在 arr[:] = x 之后, arr仍然是一个内存映射数组,而在 arr = x 之后, arr是一个ndarray。

>>> arr = np.memmap('mm', dtype='float32', mode='w+', shape=(1,10000000))
>>> type(arr)
<class 'numpy.core.memmap.memmap'>
>>> x = np.ones((1,10000000))
>>> type(x)
<class 'numpy.ndarray'>
>>> arr[:] = x
>>> type(arr)
<class 'numpy.core.memmap.memmap'>
>>> arr = x
>>> type(arr)
<class 'numpy.ndarray'>

np.argsort的情况下,它返回一个与其参数类型相同的数组。因此,在这种特定情况下,我认为执行 arr = np.argsort(x) 应该没有区别。或 arr[:] = np.argsort(x) .在您的代码中,arr2将是一个内存映射数组。但还是有区别的。

>>> arr = np.memmap('mm', dtype='float32', mode='w+', shape=(1,10000000))
>>> x = np.ones((1,10000000))
>>> arr[:] = x
>>> type(np.argsort(x))
<class 'numpy.ndarray'>
>>> type(np.argsort(arr))
<class 'numpy.core.memmap.memmap'>

好的,现在有什么不同了。使用 arr[:] = np.argsort(arr) ,如果我们查看对 memmapped 文件的更改,我们会看到对 arr 的每个更改之后都会更改文件的 md5sum。

>>> import os
>>> import numpy as np
>>> arr = np.memmap('mm', dtype='float32', mode='w+', shape=(1,10000000))
>>> arr[:] = np.zeros((1,10000000))
>>> os.system("md5sum mm")
48e9a108a3ec623652e7988af2f88867 mm
0
>>> arr += 1.1
>>> os.system("md5sum mm")
b8efebf72a02f9c0b93c0bbcafaf8cb1 mm
0
>>> arr[:] = np.argsort(arr)
>>> os.system("md5sum mm")
c3607e7de30240f3e0385b59491ac2ce mm
0
>>> arr += 1.3
>>> os.system("md5sum mm")
1e6af2af114c70790224abe0e0e5f3f0 mm
0

我们看到 arr仍然保留其 _mmap属性。

>>> arr._mmap
<mmap.mmap object at 0x7f8e0f086198>

现在使用 arr = np.argsort(x) ,我们看到 md5sums 停止变化。尽管arr的类型是内存映射数组,它是一个新对象,似乎内存映射被删除了。

>>> import os
>>> import numpy as np
>>> arr = np.memmap('mm', dtype='float32', mode='w+', shape=(1,10000000))
>>> arr[:] = np.zeros((1,10000000))
>>> os.system("md5sum mm")
48e9a108a3ec623652e7988af2f88867 mm
0
>>> arr += 1.1
>>> os.system("md5sum mm")
b8efebf72a02f9c0b93c0bbcafaf8cb1 mm
0
>>> arr = np.argsort(arr)
>>> os.system("md5sum mm")
b8efebf72a02f9c0b93c0bbcafaf8cb1 mm
0
>>> arr += 1.3
>>> os.system("md5sum mm")
b8efebf72a02f9c0b93c0bbcafaf8cb1 mm
0
>>> type(arr)
<class 'numpy.core.memmap.memmap'>

现在 '_mmap' 属性为 None。

>>> arr._mmap
>>> type(arr._mmap)
<class 'NoneType'>

现在是第 3 部分。在执行复杂操作时,似乎很容易丢失对内存映射对象的引用。我目前的理解是你必须分解并使用 arr[:] = <>中间结果。

使用 numpy 1.8.1 和 Python 3.4.1

关于python - 对 Memmapped 数组进行操作的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25567589/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com