2014-08-29 4 views
5

Операция, с которой я запутался, выглядит следующим образом. Я делаю это на обычных массивах Numpy, но на memmap я хочу получать информацию о том, как все это работает.Правильный способ выполнения операций с Memmapped массивами

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 

против

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

В чем разница?

3.

было бы больше памяти эффективной отдельно вычислить np.argsort в качестве временного memmapped массива и np.argsort(np.argsort) в качестве временного memmapped массива, а затем сделать операцию? Поскольку массив argsort массива 20 ГБ сам по себе будет довольно огромным!

Я думаю, что эти вопросы помогут мне разобраться в внутренней работе memmapped массивов в python!

Благодаря ...

ответ

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 array. Но есть разница.

>>> 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

+0

Вы должны использовать аргумент 'out', если таковой имеется. В противном случае вы всегда получаете временные копии. (конечно, операторы inplace '+ =' обычно используют аргумент out) – seberg

+0

@seberg Можете ли вы немного рассказать об этом? Что такое аргумент 'out'? – user1265125

Смежные вопросы