我需要向量化以下python代码的帮助。当前循环太慢了,无法满足我的需求。
如果a是您的列表
[-1.5,-1,-1,0,0,-1,0,1.5,1,1,1,1,0,0,0,0,1,0,1,0,1.5, 1,1,1,1,0,0,0,0,-1.5 ...]
我们在下面的当前代码之后获得所需的输出: [-1,-1,-1,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1, 1,1,0,0,0,0,-1 ...]
for index, item in enumerate(a):
if item == 1.5:
a[index] = 1
elif item == -1.5:
a[index] = -1
elif a[index] == 0:
a[index] = 0
elif (a[index] == 1 or a[index] == -1) and a[index-1] ==0:
a[index] = 0
else:
a[index] = a[index-1]
谢谢!
答案 0 :(得分:1)
按照@Bart的建议,您可以使用numpy轻松地至少对前三个操作进行矢量化。最后一个条件比较棘手,因为您需要知道前三种情况在哪里失败。您还需要注意,因为如果就地进行计算,那么早期的更改可能会影响以后的条件(即,将某些值分配为1,然后再检查等于1的值)。总而言之,您可以执行以下操作:
a = np.array(a)
cond1 = a == 1.5
cond2 = a == -1.5
cond3 = ((a == 1) | (a == -1))[1:] & (a[:-1] == 0)
cond4 = ~(cond1[1:] | cond2[1:] | cond3)
a[cond1] = 1
a[cond2] = -1
a[1:][cond3] = 0
a[1:][cond4] = a[1:][cond4]
答案 1 :(得分:0)
您可以使用熊猫:
import pandas as pd
l = [-1.5,-1,-1,0,0,-1,0,1.5,1,1,1,1,0,0,0,0,1,0,1,0,1.5,1,1,1,1,0,0,0,0,-1.5]
s = pd.Series(l)
cond1 = (s == 1.5)
cond2 = (s == -1.5)
cond3 = (s == 0)
cond4 = ((s == 1) | (s == -1)) & (s.shift() == 0)
out = pd.Series(pd.np.select([cond1, cond2, cond3, cond4],[1, -1, 0 ,0], pd.np.nan)).ffill()
out.tolist()
输出:
[-1.0,
-1.0,
-1.0,
0.0,
0.0,
0.0,
0.0,
1.0,
1.0,
1.0,
1.0,
1.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
1.0,
1.0,
1.0,
1.0,
1.0,
0.0,
0.0,
0.0,
0.0,
-1.0]
注意:这是一种矢量化的方式,如果不使用Numpy方法np.select,可以通过使用pd.np.select的熊猫导入来访问。默认值为np.nan,在这种默认情况下,允许向前填充获取以前的行值。