我对此操作感到困惑。我一直在常规的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的memmapped数组,我有几个问题:
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
VS
arr2[:] = np.argsort(np.argsort(arr1,axis=0),axis=0) / float(len(arr1)) * 100
有什么区别?
第3
单独计算np.argsort
作为临时memmapped数组并将np.argsort(np.argsort)
作为临时memmapped数组然后执行操作会更节省内存吗?由于20GB阵列的argsort数组本身就非常庞大!
我认为这些问题可以帮助我澄清python中memmapped数组的内部工作原理!
...谢谢
答案 0 :(得分:2)
我将尝试先回答第2部分,然后回答1和3。
首先,arr = <something>
是简单的变量赋值,而arr[:] = <something>
分配给数组的内容。在下面的代码中,在arr[:] = x
之后,arr
仍然是一个memmapped数组,而在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
将是一个memmapped数组。但是有区别。
>>> 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
的类型是memmapped数组,但它是一个新对象,似乎内存映射被删除。
>>> 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部分。在执行复杂操作时,似乎很容易丢失对memmapped对象的引用。我目前的理解是你必须分解并使用arr[:] = <>
来获得中间结果。
使用numpy 1.8.1和Python 3.4.1