我很困惑的操作看起来像这样.我一直在常规的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
Run Code Online (Sandbox Code Playgroud)
这是我在普通的numpy数组上使用的.
现在.考虑到arr1 现在是一个20GB的memmapped数组,我有几个问题:
1:
arr2 = np.argsort(np.argsort(arr1,axis=0),axis=0) / float(len(arr1)) * 100
Run Code Online (Sandbox Code Playgroud)
arr2将是一个常规的numpy数组,我假设?所以执行这个将是灾难性的记忆明智吗?
考虑到我现在已经创建arr2了一个正确大小的Memmapped数组(用全零填充).
2:
arr2 = np.argsort(np.argsort(arr1,axis=0),axis=0) / float(len(arr1)) * 100
Run Code Online (Sandbox Code Playgroud)
VS
arr2[:] = np.argsort(np.argsort(arr1,axis=0),axis=0) / float(len(arr1)) * 100
Run Code Online (Sandbox Code Playgroud)
有什么不同?
3.
单独计算np.argsort作为临时memmapped数组和np.argsort(np.argsort)临时memmapped数组然后执行操作会更高效吗?由于20GB阵列的argsort数组本身就相当庞大!
我认为这些问题将帮助我澄清python中memmapped数组的内部工作原理!
谢谢...
我将尝试先回答第 2 部分,然后回答第 1 部分和第 3 部分。
首先,arr = <something>是简单的变量赋值,而arr[:] = <something>赋值给数组的内容。在下面的代码中, after arr[:] = x,arrstill 是一个内存映射数组,而 after 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'>
Run Code Online (Sandbox Code Playgroud)
在 的情况下np.argsort,它返回与其参数相同类型的数组。arr = np.argsort(x)因此,在这种具体情况下,我认为 do或之间应该没有区别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'>
Run Code Online (Sandbox Code Playgroud)
好吧,现在有什么不同。使用arr[:] = np.argsort(arr),如果我们查看对 memmapping 文件的更改,我们会发现对 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
Run Code Online (Sandbox Code Playgroud)
我们看到它arr仍然保留着它的_mmap属性。
>>> arr._mmap
<mmap.mmap object at 0x7f8e0f086198>
Run Code Online (Sandbox Code Playgroud)
现在使用arr = np.argsort(x),我们看到 md5sum 停止变化。尽管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'>
Run Code Online (Sandbox Code Playgroud)
现在“_mmap”属性为 None。
>>> arr._mmap
>>> type(arr._mmap)
<class 'NoneType'>
Run Code Online (Sandbox Code Playgroud)
现在是第 3 部分。在执行复杂操作时,似乎很容易丢失对内存映射对象的引用。我目前的理解是,你必须将事情分解并用于arr[:] = <>中间结果。
使用 numpy 1.8.1 和 Python 3.4.1