高效的条件滚动计算 Pandas
Posted
技术标签:
【中文标题】高效的条件滚动计算 Pandas【英文标题】:Efficient conditional rolling calculation Pandas 【发布时间】:2020-04-11 16:22:05 【问题描述】:生成数据
random.seed(42)
date_rng = pd.date_range(start='1/1/2018', end='1/08/2018', freq='H')
df = pd.DataFrame(np.random.randint(0,10,size=(len(date_rng))),
columns=['data'],
index= date_rng)
mask = np.random.choice([1, 0], df.shape, p=[.35, .65]).astype(bool)
df[mask] = np.nan
我想计算std()
用于windows = 5的滚动,如果windows中超过一半的元素= NaN,则滚动计算等于NaN,如果windows中的元素少于一半= NaN , dropna() 并计算其余元素的 std()。
我只知道如何计算正常滚动:
df.rolling(5).std()
如何指定滚动计算的条件
【问题讨论】:
你能添加 date_rng 还是其中的一部分 我的不好,我会添加它 【参考方案1】:我认为您可以在rolling function
中使用参数min_periods
df['rollingstd'] = df.rolling(5, min_periods=3).std()
df.head(20)
Out put:
data rollingstd
2018-01-01 00:00:00 1.0 NaN
2018-01-01 01:00:00 6.0 NaN
2018-01-01 02:00:00 1.0 2.886751
2018-01-01 03:00:00 NaN 2.886751
2018-01-01 04:00:00 5.0 2.629956
2018-01-01 05:00:00 3.0 2.217356
2018-01-01 06:00:00 NaN 2.000000
2018-01-01 07:00:00 NaN NaN
2018-01-01 08:00:00 3.0 1.154701
2018-01-01 09:00:00 NaN NaN
2018-01-01 10:00:00 5.0 NaN
2018-01-01 11:00:00 9.0 3.055050
2018-01-01 12:00:00 NaN 3.055050
2018-01-01 13:00:00 9.0 2.309401
2018-01-01 14:00:00 1.0 3.829708
2018-01-01 15:00:00 0.0 4.924429
2018-01-01 16:00:00 3.0 4.031129
2018-01-01 17:00:00 0.0 3.781534
2018-01-01 18:00:00 1.0 1.224745
2018-01-01 19:00:00 NaN 1.414214
【讨论】:
我想对这个问题再补充一点,如果不是用np.nan
调节,我想要滚动返回NaN,如果窗口中的值的一半是0,那我怎么能做吗?【参考方案2】:
这是另一种更自定义的方法:
为您的逻辑编写一个自定义方法,该方法将窗口大小元素的数组作为输入并返回该窗口所需的结果:
def cus_mean(x):
notnone = ~(np.isnan(x))
if notnone.sum()>2:
return np.mean([y for y in x if ~(np.isnan(y))])
然后在您的数据帧上调用滚动函数,如下所示:
df.rolling(5).apply(cus_mean)
【讨论】:
在小例子中,forloop实现还可以,但我认为它对于大数据集效率不高 好的,for循环只对窗口大小的元素起作用,所以它是一个恒定的操作,它不会依赖于数据的大小。 2. 如果您必须为特定的用例做一些非常定制的事情,那么这是要走的路。对于您的用例,将 min_periods 与滚动一起使用是可行的。以上是关于高效的条件滚动计算 Pandas的主要内容,如果未能解决你的问题,请参考以下文章
在pandas中使用query替代loc进行高效简洁的条件筛选
在pandas中使用query替代loc进行高效简洁的条件筛选