#python #numpy #python-3.6 #memmap
#python #numpy #python-3.6 #memmap
Вопрос:
Я хотел бы отсортировать матрицу формы (N, 2)
по первому столбцу, где N
>> системная память.
С помощью numpy в памяти вы можете сделать:
x = np.array([[2, 10],[1, 20]])
sortix = x[:,0].argsort()
x = x[sortix]
Но, похоже, для этого требуется, чтобы она x[:,0].argsort()
помещалась в память, что не будет работать для memmap, где N
>> системная память (пожалуйста, поправьте меня, если это предположение неверно).
Могу ли я добиться такой сортировки на месте с помощью numpy memmap?
(предположим, что для сортировки используется heapsort и используются простые числовые типы данных)
Ответ №1:
Решение может быть простым, используя аргумент order для сортировки на месте. Конечно, order
требуются имена полей, поэтому их нужно добавить в первую очередь.
d = x.dtype
x = x.view(dtype=[(str(i), d) for i in range(x.shape[-1])])
array([[(2, 10)],
[(1, 20)]], dtype=[('0', '<i8'), ('1', '<i8')])
Имена полей представляют собой строки, соответствующие индексам столбцов. Сортировка может быть выполнена на месте с помощью
x.sort(order='0', axis=0)
Затем преобразуйте обратно в обычный массив с исходным типом данных
x.view(d)
array([[ 1, 20],
[ 2, 10]])
Это должно сработать, хотя вам может потребоваться изменить способ просмотра в зависимости от того, как данные хранятся на диске, см. Документы
Для.view(some_dtype), если some_dtype имеет другое количество байтов на запись, чем предыдущий dtype (например, преобразование обычного массива в структурированный массив), то поведение view нельзя предсказать только по внешнему виду a (показано print(a)). Это также зависит от того, как именно a хранится в памяти. Поэтому, если a упорядочен по C, а не по fortran, а не определен как срез или транспонирование и т.д., представление может давать разные результаты.
Ответ №2:
@user2699 прекрасно ответил на вопрос. Я добавляю это решение в качестве упрощенного примера на случай, если вы не возражаете сохранить свои данные в виде структурированного массива, что устраняет представление.
import numpy as np
filename = '/tmp/test'
x = np.memmap(filename, dtype=[('index', '<f2'),('other1', '<f2'),('other2', '<f2')], mode='w ', shape=(2,))
x[0] = (2, 10, 30)
x[1] = (1, 20, 20)
print(x.shape)
print(x)
x.sort(order='index', axis=0, kind='heapsort')
print(x)
(2,)
[(2., 10., 30.) (1., 20., 20.)]
[(1., 20., 20.) (2., 10., 30.)]
Также здесь задокументированы форматы dtype.