2013-05-30 10 views
2

我有一個系列發電機的創建載體,如:查找發電機的最小值的縱列指數在Python + numpy的

vector = (remainder(v, PRIME_NUMBER) for v in list_of_vectors) 

,我想生成包含的行索引的矢量矩陣由上述發生器創建,包含最小值。

我有這個迄今爲止,使用numpy的:

minv = ones(n)*PRIME_NUMBER # n is the length of each vector 
min_idx = zeros(n) 
for i,r in enumerate(vector): 
     min_idx = argmin(vstack((r,minv)),0)*min_idx 
     min_idx = [x if x>0 else i for x in min_idx] 
     minv = amin(vstack((minv,r)),0) 

當然,這是太慢了(至少我的應用程序)。我想知道有沒有更快的方法來做到這一點!

我期待想出一個辦法做到這一點,就像如果我是隻獲得了最小值:

minvalues = reduce(lambda x,y: amin(vstack((x,y)),0) , vector) 

編輯: 工作示例進行一些修改:

from numpy import random, zeros, remainder 

PRIME_NUMBER = 109297 
dim = 100 
list_of_vectors = random.rand(1000,dim) 

vector = (remainder(v, PRIME_NUMBER) for v in list_of_vectors) 

min_idx = [(0,PRIME_NUMBER)]*dim 
for i,r in enumerate(vector): 
     min_idx = map(lambda x: (i,x[0]) if x[0]<x[1][1] else x[1] , zip(r,min_idx)) 

這段代碼運行速度比以前快了50%,但我仍然認爲有一些改進空間。

+0

就程序速度而言,最耗時的操作是'vstack()'。當調用vstack時,會創建一個新對象並將舊對象複製到其中。如果這樣做一次或兩次,這沒什麼大不了的,但如果反覆完成,這種複製變得非常昂貴。如果您預先分配'minv'的全部大小,將會產生最顯着的性能提升。 – aestrivex

+0

謝謝,你的提示使我想到: 對於i,r在枚舉(向量)中: min_idx = map(lambda x:(i,x [0])如果x [0] Olivetti

+0

您可以展示「list_of_vectors」的外觀喜歡?我試圖創建一個向量列表,每個向量包含100個隨機整數來測試你的代碼,但它給出了一個錯誤... –

回答

0

這裏是什麼,我覺得你想要做一個非常簡單的版本運行速度比你的代碼快好幾倍。

vector = (np.remainder(v,PRIME_NUMBER) for v in list_of_vectors.T) 
min_idx=[np.argmin(slice) for slice in vector)] 

訣竅是注意到,dim << len(vector),因而是切片在合適的項目。你不能像你定義的那樣用發生器來做這件事。

如果你絕對必須使用指定的發電機,你可以做如vector=np.array([v for v in vector]).T。但是這完全破壞了使用發電機的目的。

+0

有一件事我忘了提及的是, list_of_vectors「也是一個生成器,所以我不能轉置。但你的回答讓我思考如何生成轉置,而我可以達到所需的速度!謝謝! – Olivetti

相關問題