我有以下数据
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
date_today = pd.Timestamp(1513393355.5, unit='s')
days = pd.date_range(date_today, date_today + timedelta(1), freq='s')
np.random.seed(seed=1111)
data_price = np.random.randint(2, high=10, size=len(days))
data_quantity = np.random.randint(2, high=100, size=len(days))
df = pd.DataFrame({'ts': days, 'price': data_price, 'quantity': data_quantity})
df = df.set_index('ts')
print(df.head())
price quantity
ts
2017-12-16 03:02:35.500 6 30
2017-12-16 03:02:36.500 9 18
2017-12-16 03:02:37.500 7 85
2017-12-16 03:02:38.500 3 51
2017-12-16 03:02:39.500 6 19
我想以10分钟为间隔对数据进行重新采样,按照价格的升序对每个10分钟窗口内的观察结果进行排名,对排名后的数据进行前20%的排序,然后计算加权平均价格(即价格加权后的价格)按数量),以及数据的前20%的数量之和。
有一个解决方案https://stackoverflow.com/a/29820981/220986,该解决方案使用groupby函数来计算加权平均价格。但是我想将加权平均值应用于总和的前20%。
我想在静态基础上(即应用熊猫重采样功能),并每隔1分钟滚动一次,回溯期为10分钟。
我如何用熊猫优雅地做到这一点?我对如何在重采样窗口中进行排名感到困惑。
谢谢!
答案 0 :(得分:0)
在这里尝试一次。我使用了10分钟的滚动窗口,因此当前值将代表过去10分钟内的任何内容。为了演示起见,我将其更改为 10秒,以便更轻松地验证计算。
逻辑是:
编辑:意识到我是在计算最高分位数,而不是观测值的前20%。保留以下原始文档,以及此处的更正版本:
views/tester.hbs
输出
def top_obs_wavg(s):
## greater than 20% of obs > valid observation
if len(s) < 5: # not enought for 20%, keep the largest
valid_index =s.nlargest(1).index
else:
valid_index = s.nlargest(len(s)//5).index ## keep all above 20%
## filter pct_qty of tot_qty for the window, only those for top price quantile (>20%)
pct_qty = df.loc[valid_index,'quantity']/np.sum(df.loc[valid_index,'quantity'])
## return the sum of the valid percentages * valid prices > weigthed average.
return np.sum(pct_qty*s[valid_index])
df['t20_wavg'] = df.rolling('10s')['price'].apply(top_obs_wavg, raw=False)
使用分位数
price quantity t20_wavg
ts
2017-12-16 03:02:35.500 6 30 6.000000
2017-12-16 03:02:36.500 9 18 9.000000
2017-12-16 03:02:37.500 7 85 9.000000
2017-12-16 03:02:38.500 3 51 9.000000
2017-12-16 03:02:39.500 6 19 9.000000
2017-12-16 03:02:40.500 4 72 9.000000
2017-12-16 03:02:41.500 6 47 9.000000
2017-12-16 03:02:42.500 2 64 9.000000
2017-12-16 03:02:43.500 8 21 9.000000
2017-12-16 03:02:44.500 6 46 8.461538
2017-12-16 03:02:45.500 5 40 8.461538
2017-12-16 03:02:46.500 8 13 8.000000
2017-12-16 03:02:47.500 2 99 8.000000
2017-12-16 03:02:48.500 8 19 8.000000
2017-12-16 03:02:49.500 6 60 8.000000
然后我们可以使用熊猫滚动类:
def top_quantile_wavg(s):
## greater than 20% quantile > valid observation
is_valid = s >= s.quantile()
valid_index = s.index[is_valid]
## filter pct_qty of tot_qty for the window, only those for top price quantile (>20%)
pct_qty = df.loc[valid_index,'quantity']/np.sum(df.loc[valid_index,'quantity'])
## return the sum of the valid percentages * valid prices > weigthed average.
return np.sum(pct_qty*s[valid_index])
输出
## change to 10T for 10 minutes
df['t20_wavg'] = df.rolling('10s')['price'].apply(top_quantile_wavg, raw=False)