我有四个长度相等的列表:A_old, A_new, B_old, B_new
并且希望有以下行为:如果A_new[i] > A_old[i]
则设置B_old[i] = B_new[i]
。
尝试了一个简单的循环实现:
for i, (a_new, a_old) in enumerate(izip(A_new, A_old)):
if a_new > a_old:
B_old[i] = B_new[i]
使用地图的实现(建议here):
B_old = map(lambda (a_new, a_old, b_new, b_old): b_new if a_new > a_old else b_old,
izip(A_new, A_old, B_new, B_old))
但这些方法都不够快。请注意,我不能使用numpy
数组和布尔数组,因为B_new, B_old
的元素不是数字。
为了使事情处于更正式的基础,这里提供了一个示例实现:https://gist.github.com/1986588,运行时如下所示:
Naive: 1.13343191147
Mapping: 1.45240283012
kev: 1.09499907494
Numpy: 0.0525879859924
Where: 0.0651860237122
评估了不同的选项numpy
切片与布尔数组似乎是要走的路。但是,我现在遇到了一个新问题:
让B_new
不是数组,而只是值val
。然后最好的变体读取
B_old[A_new > A_old] = val
只要val
不可迭代但在失败时失败,这样就可以正常工作。特别是,val
在这里是一个元组。我想将元组val
分配给B_old
A_new > A_old
的元素。
解决方法似乎是让
val2 = np.empty(1, dtype=object)
val2[0]=val
B_old[A_new > A_old] = val
但这似乎令人费解。问题是我不知道val的类型是什么。它可能是可迭代的,也可能不是。
答案 0 :(得分:3)
B_old = [B_new[i] if A_new[i]>A_old[i] else B_old[i] for i in range(len(A_old))]