我有一个熊猫数据框
cumm_vol cumm_vol_LB
datetime
2018-01-01 09:15:00 93228 0
2018-01-01 09:16:00 124353 0
2018-01-01 09:17:00 184578 0
2018-01-01 09:18:00 237003 0
2018-01-01 09:19:00 264303 0
2018-01-01 09:20:00 310503 0
2018-01-02 09:15:00 170928 0
2018-01-02 09:16:00 261528 0
2018-01-02 09:17:00 358653 0
2018-01-02 09:18:00 438678 0
2018-01-02 09:19:00 559503 0
2018-01-02 09:20:00 626178 0
2018-01-03 09:15:00 175953 0
2018-01-03 09:16:00 294078 0
2018-01-03 09:17:00 395853 0
2018-01-03 09:18:00 447078 0
2018-01-03 09:19:00 486903 0
2018-01-03 09:20:00 523578 0
2018-01-04 09:15:00 82727 0
2018-01-04 09:16:00 129077 0
2018-01-04 09:17:00 162752 0
2018-01-04 09:18:00 194852 0
2018-01-04 09:19:00 239027 0
2018-01-04 09:20:00 291677 0
我必须计算最近x天窗口中每1分钟间隔的cumm_vol
的平均值,并将其添加到当前的cumm_vol_LB
列中,例如,每天向前滚动一次。如果x = 2,则cumm_vol
在日期2018年1月1日和2018年1月2日的 cumm_vol cumm_vol_LB
datetime
2018-01-01 09:15:00 93228 0
2018-01-01 09:16:00 124353 0
2018-01-01 09:17:00 184578 0
2018-01-01 09:18:00 237003 0
2018-01-01 09:19:00 264303 0
2018-01-01 09:20:00 310503 0
2018-01-02 09:15:00 170928 0
2018-01-02 09:16:00 261528 0
2018-01-02 09:17:00 358653 0
2018-01-02 09:18:00 438678 0
2018-01-02 09:19:00 559503 0
2018-01-02 09:20:00 626178 0
2018-01-03 09:15:00 175953 132078
2018-01-03 09:16:00 294078 192940.5
2018-01-03 09:17:00 395853 271615.5
2018-01-03 09:18:00 447078 337840.5
2018-01-03 09:19:00 486903 523203
2018-01-03 09:20:00 523578 468340.5
..........
的平均值为零,而对于2018年1月3日的平均值为(93228 + 170928)/ 2 = 132078
因此,预期输出将是一种滚动平均值:
groupby
我目前正在尝试的方法是过滤回溯期= 2的日期的数据,并同时根据时间for dateix,date in enumerate(dates):
nifty_datewise = nifty_data.groupby('date').get_group(date)
nifty_datatemp = groupbytime(nifty_data, nifty_datewise, dates, dateix)
nifty_main = nifty_main.append(nifty_datatemp)
def groupbytime(nifty_datafrm, nifty_datewise, dates, dateix):
if dateix-2>=0:
nifty_data = nifty_datafrm.loc[dates[dateix-2]: dates[dateix]]
datesNew = nifty_data["date"].dt.date.unique()
lookback_df = pd.DataFrame()
for datei,date in enumerate(datesNew):
nifty_df = nifty_data.groupby('date').get_group(date)
lookback_df = lookback_df.append(nifty_df)
nifty_datewise["cumm_vol_LB"] = lookback_df.groupby('time')['cumm_vol'].transform('mean')
return nifty_datewise
else:
return nifty_datewise
进行转换并构建新的数据框。
.rolling
这似乎不是最佳解决方案。寻找最佳实践来实现这一目标,也许熊猫已经为这种用例内置了某些功能,for (i=0; i<n-1; i++)
{
for (j=0; j<n-i-1; j++)
{
digit=a[j]%10;
while (a[j]>0)
{
if (a[j]%10!=digit)
same=0;
a[j]/=10;
}
digit1=a[j+1]%10;
while (a[j+1]>0)
{
if (a[j+1]%10!=digit1)
same1=0;
a[j+1]/=10;
}
if (same==0 && same1==1)
{
temp=a[j+1];
a[j+1]=a[j];
a[j]=temp;
}
}
}
却无济于事,因为它逐行工作。
谢谢
答案 0 :(得分:1)
重构我的第一个答案时,我发现熊猫对时间序列数据有很好的处理能力。您可以阅读here。而且,将数据与groupby
分组似乎非常有效,并且不会像我最初想象的那样创建多余的数据副本。
答案A在数据集大小上的缩放比例(线性)要比答案B好得多。我可以在大约100毫秒内计算20k大小写(用%timeit
中的ipython
进行度量)。在下面找到我正在测试的数据的摘录。
此方法按分钟对数据进行分组,然后对各组应用移动平均滤波器。阅读here有关熊猫窗口功能的信息。 here给出了用于指定时间增量的可用偏移别名的列表。
def assign_rolling_average(x, dt):
x.cumm_vol_LB = x.cumm_vol.rolling(window=dt).mean()
return x
dt='3D' # width of rolling average window: 3 days
# Group data by the time.
g = df.groupby(lambda x: x.time())
# Apply the moving average filter on all groups.
df = g.apply(assign_rolling_average, dt=dt)
这是我最初的答案。它手动标识要操作的行。它涉及具有全长逻辑索引的多个操作,并且可能会受到data locality problems的影响。它在运行时按问题大小呈二次方缩放。
from datetime import timedelta
# Time delta: fix here the width of the time window
dt = timedelta(days=3)
# Iterate over the rows
for idx in df.index:
date, time = idx.date(), idx.time()
mask = ((df.index.time == time) # Same time of the day
& (df.index.date <= date) # Not later than today
& (df.index.date >= (date-dt))) # Not older than (today - dt)
df.loc[idx, 'cumm_vol_LB'] = df.loc[mask, 'cumm_vol'].mean()
这是我测试过的数据框:
import pandas as pd
df = pd.DataFrame([["2018-01-01 09:15:00", 93228, 0],
["2018-01-01 09:16:00", 124353, 0],
["2018-01-01 09:17:00", 184578, 0],
["2018-01-01 09:18:00", 237003, 0],
["2018-01-01 09:19:00", 264303, 0],
["2018-01-01 09:20:00", 310503, 0],
["2018-01-02 09:15:00", 170928, 0],
["2018-01-02 09:16:00", 261528, 0],
["2018-01-02 09:17:00", 358653, 0],
["2018-01-02 09:18:00", 438678, 0],
["2018-01-02 09:19:00", 559503, 0],
["2018-01-02 09:20:00", 626178, 0],
["2018-01-03 09:15:00", 175953, 0],
["2018-01-03 09:16:00", 294078, 0],
["2018-01-03 09:17:00", 395853, 0],
["2018-01-03 09:18:00", 447078, 0],
["2018-01-03 09:19:00", 486903, 0],
["2018-01-03 09:20:00", 523578, 0],
["2018-01-04 09:15:00", 82727, 0],
["2018-01-04 09:16:00", 129077, 0],
["2018-01-04 09:17:00", 162752, 0],
["2018-01-04 09:18:00", 194852, 0],
["2018-01-04 09:19:00", 239027, 0],
["2018-01-04 09:20:00", 291677, 0]],
columns = ['datetime', 'cumm_vol', 'cumm_vol_LB']
)
df = df.set_index('datetime')
df.index = pd.to_datetime(df.index)