Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python试图减少对循环的依赖_Python_Pandas_Vectorization - Fatal编程技术网

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