0

我想在>> 系统内存(N, 2)的第一列对形状矩阵进行排序。N

使用内存中的 numpy,您可以执行以下操作:

x = np.array([[2, 10],[1, 20]])
sortix = x[:,0].argsort()
x = x[sortix]

但这似乎需要x[:,0].argsort()适合内存,这不适用于 memmap where N>> 系统内存(如果这个假设是错误的,请纠正我)。

我可以使用 numpy memmap 就地实现这种排序吗?

(假设使用 heapsort 进行排序,使用简单的数值数据类型)

4

2 回答 2

2

解决方案可能很简单,使用就地排序的 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]])

这应该可行,尽管您可能需要根据数据在磁盘上的存储方式来更改视图的获取方式,请参阅文档

对于 a.view(some_dtype),如果 some_dtype 每个条目的字节数与前一个 dtype 不同(例如,将常规数组转换为结构化数组),那么仅从表面外观无法预测视图的行为a(由 print(a) 显示)。它还取决于 a 是如何存储在内存中的。因此,如果 a 是 C-ordered 与 fortran-ordered,与定义为切片或转置等,则视图可能会给出不同的结果。

于 2019-03-13T21:44:35.400 回答
0

@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 格式。

于 2019-03-13T22:18:29.900 回答