答案 0 :(得分:3)
创建宽度为5的滚动总和宽度,查看从第5到末尾的所有列,如果值始终为3或以上,则选择它们:
rolling_sum = df.rolling(5, min_periods=1, axis=1).sum()
select = (rolling_sum.iloc[:, 4:] >= 3).all(axis=1)
In [92]: df
Out[92]:
0 1 2 3 4 5 6 7 8 9
0 0 0 0 0 0 0 0 0 0 0
1 0 1 0 0 1 0 1 1 0 0
2 0 1 0 1 1 0 0 1 0 0
3 0 1 1 1 0 1 1 1 1 1
4 0 1 0 1 1 1 0 0 1 1
5 0 0 1 1 1 0 1 1 1 0
In [94]: (df.rolling(5, min_periods=1, axis=1).sum().iloc[:, 4:] >= 3).all(axis=1)
Out[94]:
0 False
1 False
2 False
3 True
4 True
5 True
dtype: bool
答案 1 :(得分:2)
将基础数组数据重塑为3D
,以使最后一个轴具有5
个元素,每个元素代表每个5
的块,然后沿该轴求和,以得出每个元素的和块,最后沿代表原始数据帧每一行的第二个轴使用any
缩减-
df['result'] = (df.values.reshape(-1,df.shape[1]//5,5).sum(2)>=3).any(1)
为了提高性能,您可能需要使用布尔数组:df.values==1
而不是df.values
。
样品运行-
In [41]: df
Out[41]:
0 1 2 3 4 5 6 7 8 9
0 0 1 1 0 0 1 0 0 0 1
1 0 0 0 0 0 0 1 0 1 1
2 0 1 1 0 0 1 1 0 0 1
3 1 1 1 1 0 0 0 1 0 1
4 0 1 1 1 0 1 1 1 1 0
5 0 0 0 0 1 0 0 1 1 1
6 0 0 1 0 1 1 0 0 0 1
In [42]: df['result'] = (df.values.reshape(-1,df.shape[1]//5,5).sum(2)>=3).any(1)
In [43]: df
Out[43]:
0 1 2 3 4 5 6 7 8 9 result
0 0 1 1 0 0 1 0 0 0 1 False
1 0 0 0 0 0 0 1 0 1 1 True
2 0 1 1 0 0 1 1 0 0 1 True
3 1 1 1 1 0 0 0 1 0 1 True
4 0 1 1 1 0 1 1 1 1 0 True
5 0 0 0 0 1 0 0 1 1 1 True
6 0 0 1 0 1 1 0 0 0 1 False
如果列数不是5
的倍数,我们可以使用np.add.reduceat
-
idx = np.arange(0,df.shape[1],5)
df['result'] = (np.add.reduceat(df.values, idx, axis=1)>=3).any(1)
millions rows and tens of cols
上的时间-
In [99]: np.random.seed(0)
...: a = (np.random.rand(1000000,20)>0.6).astype(int)
...: df = pd.DataFrame(a)
# Solution from this post
In [101]: %timeit (df.values.reshape(-1,df.shape[1]//5,5).sum(2)>=3).any(1)
10 loops, best of 3: 65.3 ms per loop
# @w-m's soln
In [102]: %timeit (df.rolling(5, min_periods=1, axis=1).sum().iloc[:, 4:] >= 3).all(axis=1)
1 loop, best of 3: 8.04 s per loop