Numpy memmap на месте сортирует большую матрицу по столбцам - PullRequest
0 голосов
/ 13 марта 2019

Я бы хотел отсортировать матрицу формы (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 и используются простые числовые типы данных)

Ответы [ 2 ]

1 голос
/ 14 марта 2019

Решение может быть простым, используя аргумент порядка на месте sort . Конечно, 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]])

Это должно работать, хотя вам может понадобиться изменить способ просмотра в зависимости от того, как данные хранятся на диске, см. Документация

Для a.view (some_dtype), если some_dtype имеет другое количество байтов на запись, чем предыдущий dtype (например, преобразование обычного массива в структурированный массив), поведение представления не может быть предсказано только из поверхностный вид (показано печатью (а)). Это также зависит от того, как именно хранится в памяти. Следовательно, если a является C-упорядоченным по сравнению с Fortran-упорядоченным, а не определенным как срез или транспонирование и т. Д., Представление может дать разные результаты.

0 голосов
/ 14 марта 2019

@ 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 задокументированы здесь .

...