Numpy memmap 按列对大矩阵进行就地排序
Numpy memmap in-place sort of a large matrix by column
我想在 N
>> 系统内存的第一列对形状为 (N, 2)
的矩阵进行排序。
使用内存中的 numpy 你可以做:
x = np.array([[2, 10],[1, 20]])
sortix = x[:,0].argsort()
x = x[sortix]
但这似乎要求 x[:,0].argsort()
适合内存,这不适用于 N
>> 系统内存的 memmap(如果此假设错误,请纠正我)。
我可以使用 numpy memmap 就地实现这种排序吗?
(假设使用heapsort进行排序,使用简单数值数据类型)
解决方案可能很简单,使用顺序参数就地 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]])
这应该可行,但您可能需要根据数据在磁盘上的存储方式更改视图的显示方式,请参阅 the docs
For a.view(some_dtype), if some_dtype has a different number of bytes per entry than the previous dtype (for example, converting a regular array to a structured array), then the behavior of the view cannot be predicted just from the superficial appearance of a (shown by print(a)). It also depends on exactly how a is stored in memory. Therefore if a is C-ordered versus fortran-ordered, versus defined as a slice or transpose, etc., the view may give different results.
@user2699 回答问题很漂亮。我添加这个解决方案作为一个简化示例,以防您不介意将数据保留为 structured array,这会消除视图。
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 格式也是 documented here。
我想在 N
>> 系统内存的第一列对形状为 (N, 2)
的矩阵进行排序。
使用内存中的 numpy 你可以做:
x = np.array([[2, 10],[1, 20]])
sortix = x[:,0].argsort()
x = x[sortix]
但这似乎要求 x[:,0].argsort()
适合内存,这不适用于 N
>> 系统内存的 memmap(如果此假设错误,请纠正我)。
我可以使用 numpy memmap 就地实现这种排序吗?
(假设使用heapsort进行排序,使用简单数值数据类型)
解决方案可能很简单,使用顺序参数就地 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]])
这应该可行,但您可能需要根据数据在磁盘上的存储方式更改视图的显示方式,请参阅 the docs
For a.view(some_dtype), if some_dtype has a different number of bytes per entry than the previous dtype (for example, converting a regular array to a structured array), then the behavior of the view cannot be predicted just from the superficial appearance of a (shown by print(a)). It also depends on exactly how a is stored in memory. Therefore if a is C-ordered versus fortran-ordered, versus defined as a slice or transpose, etc., the view may give different results.
@user2699 回答问题很漂亮。我添加这个解决方案作为一个简化示例,以防您不介意将数据保留为 structured array,这会消除视图。
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 格式也是 documented here。