【问题标题】:How do you construct an array suitable for numpy sorting?你如何构造一个适合 numpy 排序的数组?
【发布时间】:2010-10-08 07:10:51
【问题描述】:

我需要同时对两个数组进行排序,或者更确切地说,我需要对其中一个数组进行排序,并在排序时将其关联数组的相应元素带入其中。也就是说,如果数组是 [(5, 33), (4, 44), (3, 55)] 并且我按第一个轴排序(标记在 dtype='alpha' 下面)那么我想要: [(3.0, 55.0 ) (4.0, 44.0) (5.0, 33.0)]。这些是非常大的数据集,我需要先排序(对于 nlog(n) 速度),然后再执行一些其他操作。我不知道如何以正确的方式合并我的两个单独的数组以使排序算法正常工作。我认为我的问题很简单。我尝试了三种不同的方法:

import numpy
x=numpy.asarray([5,4,3])
y=numpy.asarray([33,44,55])

dtype=[('alpha',float), ('beta',float)]

values=numpy.array([(x),(y)])
values=numpy.rollaxis(values,1)
#values = numpy.array(values, dtype=dtype)
#a=numpy.array(values,dtype=dtype)
#q=numpy.sort(a,order='alpha')
print "Try 1:\n", values

values=numpy.empty((len(x),2))
for n in range (len(x)):
        values[n][0]=y[n]
        values[n][1]=x[n]
print "Try 2:\n", values
#values = numpy.array(values, dtype=dtype)
#a=numpy.array(values,dtype=dtype)
#q=numpy.sort(a,order='alpha')

###
values = [(x[0], y[0]), (x[1],y[1]) , (x[2],y[2])]
print "Try 3:\n", values
values = numpy.array(values, dtype=dtype)
a=numpy.array(values,dtype=dtype)
q=numpy.sort(a,order='alpha')

print "Result:\n",q

我注释掉了第一次和第二次尝试,因为它们会产生错误,我知道第三次会起作用,因为这反映了我在 RTFM 时看到的情况。给定数组 x 和 y(它们非常大,仅显示示例)如何构造可以由 numpy.sort 正确调用的数组(称为值)?

*** Zip 很好用,谢谢。额外问题:我以后如何将排序后的数据再次解压缩到两个数组中?

【问题讨论】:

    标签: python algorithm arrays numpy


    【解决方案1】:

    我认为你想要的是 zip 功能。如果你有

    x = [1,2,3]
    y = [4,5,6]
    

    然后zip(x,y) == [(1,4),(2,5),(3,6)]

    所以你的数组可以使用

    a = numpy.array(zip(x,y), dtype=dtype)
    

    【讨论】:

    • +1:zip 可以很好地与生成器配合使用,因此您不必创建巨大的内存列表,而是可以使用生成器函数。
    • 我以后如何才能将排序后的数据再次解压到两个数组中?
    • 一旦上面有a,就可以用c, d = zip(*a)解压了。
    【解决方案2】:

    对于您的额外问题 - zip 实际上也解压缩:

    In [1]: a = range(10)
    In [2]: b = range(10, 20)
    In [3]: c = zip(a, b)
    In [4]: c
    Out[4]: 
    [(0, 10),
     (1, 11),
     (2, 12),
     (3, 13),
     (4, 14),
     (5, 15),
     (6, 16),
     (7, 17),
     (8, 18),
     (9, 19)]
    In [5]: d, e = zip(*c)
    In [6]: d, e
    Out[6]: ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9), (10, 11, 12, 13, 14, 15, 16, 17, 18, 19))
    

    【讨论】:

      【解决方案3】:

      Simon 建议将argsort 作为替代方法;我会推荐它作为要走的路。没有混乱的合并、压缩或解压缩:只需按索引访问。

      idx = numpy.argsort(x)
      ans = [ (x[idx[i]],y[idx[i]]) for i in idx]
      

      【讨论】:

        【解决方案4】:

        zip() 可能对于大型数组效率低下。可以使用numpy.dstack() 代替zip

        ndx = numpy.argsort(x)
        values = numpy.dstack((x[ndx], y[ndx]))
        

        【讨论】:

        • 谢谢,据我所知,这是给出的最快答案(我没有做过任何速度测试,但我真的怀疑构建一个 zip 然后解压缩它是最快的)跨度>
        • 实际上 np.take(x,ndx) 比花式索引更快。 http://wesmckinney.com/blog/?p=215
        【解决方案5】:

        我认为您只需要在制作最终 ndarray 时指定要排序的轴。或者,对原始数组之一进行 argsort,您将拥有一个索引数组,可用于在 x 和 y 中查找,这可能意味着您根本不需要值。

        (scipy.org 现在似乎无法访问,否则我会向您发布一些文档的链接)

        鉴于您的描述与您的代码 sn-p 不太匹配,很难肯定地说,但我认为您的 numpy 数组的创建过于复杂。

        【讨论】:

          【解决方案6】:

          我无法使用 Numpy 的 sort 函数获得可行的解决方案,但这里有其他可行的解决方案:

          import numpy
          x = [5,4,3]
          y = [33,44,55]
          r = numpy.asarray([(x[i],y[i]) for i in numpy.lexsort([x])])
          

          lexsort 返回数组索引的排列,将行按排序顺序排列。如果您希望您的结果按多个键排序,例如通过x,然后通过y,请改用numpy.lexsort([x,y])

          【讨论】:

            猜你喜欢
            • 2015-07-14
            • 2019-08-07
            • 2015-09-11
            • 1970-01-01
            • 2019-07-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多