2009-02-18 49 views
1

我需要同時對兩個數組進行排序,或者更確切地說,我需要對其中一個數組進行排序,並在排序時將其相關數組的相應元素與它相關聯。也就是說,如果數組是[(5,33),(4,44),(3,55)],我按第一個軸排序(標記在dtype ='alpha'下面),那麼我想:[(3.0,55.0 )(4.0,44.0)(5.0,33.0)]。這些都是大數據集,我需要先進行排序(對於nlog(n)速度),然後再執行其他操作。我不知道如何以適當的方式合併我的兩個單獨的數組,以使排序算法正常工作。我認爲我的問題很簡單。我嘗試三種不同的方法:如何構建適合numpy排序的數組?

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很好,謝謝。獎金問題:我以後如何將排序後的數據再次解壓到兩個數組中?

回答

6

我想你想要的是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) 
+0

+1:壓縮效果很好搭配發電機使用,所以您不必創建巨大的內存列表,你可以使用發電機的功能來代替。 – 2009-02-18 12:01:04

+0

我以後如何將排序的數據再次解壓到兩個數組中? – Alex 2009-02-18 18:57:52

2

我認爲你只需要指定當你製作完最後的ndarray時排序的軸。或者,您可以使用原始數組中的一個數組,並且您將擁有一個索引數組,您可以使用它來在x和y中查找,這可能意味着您根本不需要數值。

(scipy.org似乎是不可到達的,現在我還是會後你一個鏈接到一些文檔)

鑑於你的描述不完全匹配您的代碼段,很難肯定地說,但我認爲你已經過度複雜了你的numpy數組的創建。

1

使用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])代替。

3

你的獎金問題 - 實際上壓縮解壓太:

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

西蒙建議argsort作爲一種替代方法;我會推薦它作爲要走的路。沒有凌亂的合併,壓縮或解壓縮:只需通過索引進行訪問。

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

zip()可能是低效的大型陣列。numpy.dstack()可以用來代替的zip

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