2011-07-20 108 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