我正在寻找更智能,更好的解决方案。
我想根据标签内容将不同的缩放因子应用于数字字段。希望以下代码可以说明我想要实现的目标:
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个。
我们可以使用任何矩阵或linalg技巧吗?
ndarray可以接受单元格中的文本值吗?
答案 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的查找(必须对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 :(得分: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
答案 2 :(得分:0)
我认为numpy不能帮助你。顺便说一句,它是ndarray
,而不是nparray
...
也许你可以用发电机做到这一点。见http://www.dabeaz.com/generators/index.html