熊猫滚动:聚合布尔值

Rau*_*ier 6 python numpy pandas

pandas.DataFrame 中是否有滚动“任何”函数?或者还有其他方法可以在滚动函数中聚合布尔值吗?

考虑:

import pandas as pd
import numpy as np

s = pd.Series([True, True, False, True, False, False, False, True])

# this works but I don't think it is clear enough - I am not
# interested in the sum but a logical or!
s.rolling(2).sum() > 0  

# What I would like to have:
s.rolling(2).any()
# AttributeError: 'Rolling' object has no attribute 'any'
s.rolling(2).agg(np.any)
# Same error! AttributeError: 'Rolling' object has no attribute 'any'
Run Code Online (Sandbox Code Playgroud)

那么聚合布尔值时可以使用哪些函数?(如果 numpy.any 不起作用)https://pandas.pydata.org/pandas-docs/version/0.23.4/ generated/pandas.DataFrame.rolling.html 上的滚动文档指出“窗口或滚动子-针对特定操作进行分类”被返回,这并没有真正的帮助。

adr*_*adr 7

您可以像这样聚合布尔值:

# logical or
s.rolling(2).max().astype(bool)

# logical and
s.rolling(2).min().astype(bool)
Run Code Online (Sandbox Code Playgroud)

要处理来自不完整窗口的 NaN 值,您可以fillna在类型转换之前使用适当的 或 的min_periods参数rolling。取决于您要实现的逻辑。

遗憾的是,如果不将中间值创建为浮点数,则无法在 pandas 中完成此操作。


jez*_*ael 3

这个方法没有实现,关闭,你需要的是使用Rolling.apply

s = s.rolling(2).apply(lambda x: x.any(), raw=False)
print (s)
0    NaN
1    1.0
2    1.0
3    1.0
4    1.0
5    0.0
6    0.0
7    1.0
dtype: float64

s = s.rolling(2).apply(lambda x: x.any(), raw=False).fillna(0).astype(bool)
print (s)
0    False
1     True
2     True
3     True
4     True
5    False
6    False
7     True
dtype: bool
Run Code Online (Sandbox Code Playgroud)

这里更好的是使用strides - 生成 numpy 2d 数组并稍后处理:

s = pd.Series([True, True, False, True, False, False, False, True])

def rolling_window(a, window):
    shape = a.shape[:-1] + (a.shape[-1] - window + 1, window)
    strides = a.strides + (a.strides[-1],)
    return np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides)

a = rolling_window(s.to_numpy(), 2)
print (a)
[[ True  True]
 [ True False]
 [False  True]
 [ True False]
 [False False]
 [False False]
 [False  True]]

print (np.any(a, axis=1))
[ True  True  True  True False False  True]
Run Code Online (Sandbox Code Playgroud)

这里NaN省略了pandas的第一个值,可以添加第一个值进行处理,这里的Falses:

n = 2
x = np.concatenate([[False] * (n), s])

def rolling_window(a, window):
    shape = a.shape[:-1] + (a.shape[-1] - window + 1, window)
    strides = a.strides + (a.strides[-1],)
    return np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides)
a = rolling_window(x, n)
print (a)
[[False False]
 [False  True]
 [ True  True]
 [ True False]
 [False  True]
 [ True False]
 [False False]
 [False False]
 [False  True]]

print (np.any(a, axis=1))
[False  True  True  True  True  True False False  True]
Run Code Online (Sandbox Code Playgroud)