【问题标题】:Numpy memmap in-place sort of a large matrix by columnNumpy memmap 按列对大型矩阵进行就地排序
【发布时间】:2019-03-13 20:38:27
【问题描述】:

我想在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 就地实现这种排序吗?

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

【问题讨论】:

    标签: python numpy python-3.6 memmap


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

      @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

      【讨论】:

        猜你喜欢
        • 2021-03-08
        • 1970-01-01
        • 2012-04-22
        • 1970-01-01
        • 1970-01-01
        • 2016-09-27
        • 1970-01-01
        • 1970-01-01
        • 2021-06-29
        相关资源
        最近更新 更多