2011-07-20 64 views
4

我在尋找更智能,更好的解決方案。Numpy:是否可以使用numpy和ndarray替換此代碼片段中的循環?

我想根據標籤內容將不同的縮放因子應用於數字字段。希望下面的代碼能說明什麼,我想實現:

PS = [('A', 'LABEL1', 20), 
('B', 'LABEL2', 15), 
('C', 'LABEL3', 120), 
('D', 'LABEL1', 3),] 

FACTOR = [('LABEL1', 0.1), ('LABEL2', 0.5), ('LABEL3', 10)] 

d_factor = dict(FACTOR) 

for p in PS: 
     newp = (p[0], p[1], p[2]*d_factor[p[1]]) 
     print newp 

這是一個很瑣碎的操作,但我需要至少一個百萬行的數據集執行它。

所以,當然越快越好。

這些因素會事先知道,他們的數量不會超過20到30。

  1. 是否有任何矩陣或linalg技巧我們可以使用?

  2. ndarray可以在單元格中接受文本值嗎?

回答

0

我不認爲numpy可以幫助你。順便說一句,它是ndarray,而不是nparray ...

也許你可以做一個發電機。請參閱http://www.dabeaz.com/generators/index.html

+0

感謝您指出錯誤的數組名稱。修正了標題和內容 –

4

如果要混合數據類型,您將需要structured arrays

如果你打算要在查找數組匹配值的索引你想searchsorted

你舉的例子是這樣的:

>>> import numpy as np 
>>> PS = np.array([ 
    ('A', 'LABEL1', 20), 
    ('B', 'LABEL2', 15), 
    ('C', 'LABEL3', 120), 
    ('D', 'LABEL1', 3),], dtype=('a1,a6,i4')) 
>>> FACTOR = np.array([ 
    ('LABEL1', 0.1), 
    ('LABEL2', 0.5), 
    ('LABEL3', 10)],dtype=('a6,f4')) 

你的結構化數組:

>>> PS 
array([('A', 'LABEL1', 20), ('B', 'LABEL2', 15), ('C', 'LABEL3', 120), 
     ('D', 'LABEL1', 3)], 
     dtype=[('f0', '|S1'), ('f1', '|S6'), ('f2', '<i4')]) 
>>> FACTOR 
array([('LABEL1', 0.10000000149011612), ('LABEL2', 0.5), ('LABEL3', 10.0)], 
     dtype=[('f0', '|S6'), ('f1', '<f4')]) 

你可以像這樣訪問各個領域(或者你可以給他們的名字,看文檔):

>>> FACTOR['f0'] 
array(['LABEL1', 'LABEL2', 'LABEL3'], 
     dtype='|S6') 

如何在PS進行因子的查找(FACTOR必須進行排序):

>>> idx = np.searchsorted(FACTOR['f0'], PS['f1']) 
>>> idx 
array([0, 1, 2, 0]) 
>>> FACTOR['f1'][idx] 
array([ 0.1, 0.5, 10. , 0.1], dtype=float32) 

現在只需要創建一個新的陣列和乘法:

>>> newp = PS.copy() 
>>> newp['f2'] *= FACTOR['f1'][idx] 
>>> newp 
array([('A', 'LABEL1', 2), ('B', 'LABEL2', 7), ('C', 'LABEL3', 1200), 
     ('D', 'LABEL1', 0)], 
     dtype=[('f0', '|S1'), ('f1', '|S6'), ('f2', '<i4')]) 
1

如果比較兩個numpy的陣列,你會得到相應的索引。您可以使用這些索引進行集體操作。這可能不是最快的修改,但它很簡單明瞭。如果PS需要顯示結構,則可以使用自定義dtype並使用Nx3陣列。

import numpy as np 

col1 = np.array(['a', 'b', 'c', 'd']) 
col2 = np.array(['1', '2', '3', '1']) 
col3 = np.array([20., 15., 120., 3.]) 

factors = {'1': 0.1, '2': 0.5, '3': 10, } 

for label, fac in factors.iteritems(): 
    col3[col2==label] *= fac 

print col3