python试图减少对循环的依赖
这是一个关于矢量化的一般性问题,但我将使用一个示例来帮助提问。我有一个数据帧python试图减少对循环的依赖,python,pandas,vectorization,Python,Pandas,Vectorization,这是一个关于矢量化的一般性问题,但我将使用一个示例来帮助提问。我有一个数据帧df和df[col\u 1]bool(真/假)。 在df[col_2]中,我想根据第1列df[col_1][I-6:I-1]的前五行是否包含与df[col_1][I]匹配的内容,返回另一个True/False 这是我现在使用的循环,但它是许多循环中的一个,因此我认为随着数据越来越大,它们一定会减慢速度: for i in df.index: if i < 6: df[col_2][i] = 0. e
df
和df[col\u 1]
bool(真/假)。
在df[col_2]
中,我想根据第1列df[col_1][I-6:I-1]
的前五行是否包含与df[col_1][I]
匹配的内容,返回另一个True/False
这是我现在使用的循环,但它是许多循环中的一个,因此我认为随着数据越来越大,它们一定会减慢速度:
for i in df.index:
if i < 6:
df[col_2][i] = 0.
else:
df[col_2][i] = df[col_1][i] not in tuple(df[col_1].ix[i-6:i-1,col_1)
如何在熊猫中使用矢量化实现这一点?可能使用
shift()
或偏移函数?这里有一个简单的矢量化解决方案,应该非常快,尽管可能有一种更优雅的编写方法。如果愿意,您可以忽略前5行或将其覆盖为NaN
df = pd.DataFrame({ 'col_1':[True,True,True,True,False,False,False,False,
False,True,False,False,False,False,True,True,
True,True,True,True,False] })
df['col_2'] = ((df!=df.shift(1)) & (df!=df.shift(2)) & (df!=df.shift(3)) &
(df!=df.shift(4)) & (df!=df.shift(5)))
如果速度真的很重要,你可以做如下的事情。它比上面的速度快3倍多,并且可能与您在这里所能做的一样高效。这只是利用了一个事实,即rolling_sum()
将布尔值解释为0/1,您只需要知道总和是0还是5
df['rollsum'] = pd.rolling_sum(df.col_1,6) - df.col_1
df['col_3'] = ( ((df.col_1==True ) & (df.rollsum==0))
| ((df.col_1==False) & (df.rollsum==5)) )
col_1 col_2 rollsum col_3
0 True True NaN False
1 True False NaN False
2 True False NaN False
3 True False NaN False
4 False True NaN False
5 False False 4 False
6 False False 3 False
7 False False 2 False
8 False False 1 False
9 True True 0 True
10 False False 1 False
11 False False 1 False
12 False False 1 False
13 False False 1 False
14 True False 1 False
15 True False 1 False
16 True False 2 False
17 True False 3 False
18 True False 4 False
19 True False 5 False
20 False True 5 True
在问题中加入样本数据和结果总是一个好主意。。。我想不出一个简洁的方法来实现这一点,但使用
shift()
来完成上述操作肯定会更快,即使您有5个。此外,上面的代码不是工作代码,因此很难检查可能的答案(没有工作代码和/或示例结果)。明白了,我已经添加了应该是什么结果。不知道为什么它不起作用-我更改了名称以使其更易于阅读,但应该仍然有效。谢谢,只要显示结果就足够了。只需要弄清楚你到底想做什么。太好了,谢谢。假设将df['col_1']替换为df将以相同的方式工作。真的很感谢你看。是的,应该可以。我只是选择了快捷方式,因为“col_1”是我的示例中唯一的变量。两者都可以工作,但第二个版本会根据不同的回溯周期进行动态调整。此外,只要更换单循环,我的总运行时间就会减少10-15%。非常聪明,再次感谢。
df['rollsum'] = pd.rolling_sum(df.col_1,6) - df.col_1
df['col_3'] = ( ((df.col_1==True ) & (df.rollsum==0))
| ((df.col_1==False) & (df.rollsum==5)) )
col_1 col_2 rollsum col_3
0 True True NaN False
1 True False NaN False
2 True False NaN False
3 True False NaN False
4 False True NaN False
5 False False 4 False
6 False False 3 False
7 False False 2 False
8 False False 1 False
9 True True 0 True
10 False False 1 False
11 False False 1 False
12 False False 1 False
13 False False 1 False
14 True False 1 False
15 True False 1 False
16 True False 2 False
17 True False 3 False
18 True False 4 False
19 True False 5 False
20 False True 5 True