Я собираюсь попытаться ответить на часть 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
Вы должны использовать аргумент 'out', если таковой имеется. В противном случае вы всегда получаете временные копии. (конечно, операторы inplace '+ =' обычно используют аргумент out) – seberg
@seberg Можете ли вы немного рассказать об этом? Что такое аргумент 'out'? – user1265125