熊猫:过去k天的平均值

时间:2018-10-22 20:38:41

标签: python pandas

我想计算最近k次出现的(FLIGHT_DURATION)滚动平均值。关于FLIGHT_DATE给出的顺序,last表示最后的位置。

就像我在以下示例中所做的那样:

ARRIVAL_AIRPORT ARRIVAL_RUNWAY  DEPARTURE_AIRPORT DEPARTURE_RUNWAY

FLIGHT_DATE FLIGHT_DURATION FLIGHT_NUMBER
0   FRA YYY HAM XXX 2000-01-01  11  1
1   FRA YYY HAM XXX 2000-01-02  12  1
2   FRA YYY HAM XXX 2000-01-03  13  1
3   FRA YYY HAM XXX 2000-01-04  14  1
4   FRA YYY HAM XXX 2000-01-05  15  1

期望k = 3:

解决方案:

ExampleA = ExampleA.groupby('FLIGHT_NUMBER').apply(lambda x: x.set_index('FLIGHT_DATE').resample('1D').first())

df1 = ExampleA.groupby(level=0)['FLIGHT_DURATION'].apply(lambda x: x.shift().rolling(min_periods=3,window=3).mean()).reset_index(name='Value_Average_Past_2_days')

pd.merge(ExampleA, df1, on=['FLIGHT_NUMBER', 'FLIGHT_DATE'], how='left')

输出:

FLIGHT_DATE ARRIVAL_AIRPORT ARRIVAL_RUNWAY  DEPARTURE_AIRPORT   
DEPARTURE_RUNWAY    FLIGHT_DURATION FLIGHT_NUMBER    
Value_Average_Past_3_days
0   2000-01-01  FRA YYY HAM XXX 11  1   NaN
1   2000-01-02  FRA YYY HAM XXX 12  1   NaN
2   2000-01-03  FRA YYY HAM XXX 13  1   NaN
3   2000-01-04  FRA YYY HAM XXX 14  1   12.0
4   2000-01-05  FRA YYY HAM XXX 15  1   13.0

如您所见,我添加了一个显示平均值的新列。至少需要三天。

问题:

现在我有了一个更复杂的数据框:

FLIGHT_NUMBER FLIGHT_DATE DEPARTURE_AIRPORT ARRIVAL_AIRPORT 
DEPARTURE_RUNWAY ARRIVAL_RUNWAY FLIGHT_DURATION

 1 01.01.2000,HAM,FRA,XXX,YYY,11   -- NaN
 1 02.01.2000,HAM,FRA,XXX,YYY,12   -- NaN
 1 03.01.2000,HAM,FRA,XXX,YYY,13   -- NaN
 1 04.01.2000,HAM,FRA,XXX,ZZZ,101  -- NaN
 1 05.01.2000,HAM,FRA,XXX,YYY,14   -- 12
 1 06.01.2000,HAM,FRA,XXX,ZZZ,102  -- NaN
 9 01.01.2000,BOG,FRA,XXX,YYY,1001 -- NaN
 1 07.01.2000,HAM,FRA,XXX,ZZZ,103  -- NaN
 9 01.01.2000,BOG,FRA,XXX,YYY,1002 -- NaN
 9 02.01.2000,BOG,FRA,XXX,YYY,1003 -- NaN
 9 03.01.2000,BOG,FRA,XXX,YYY,1004 -- 1002
 1 08.01.2000,HAM,FRA,XXX,ZZZ,104  -- 102
 1 09.01.2000,HAM,FRA,XXX,YYY,15   -- 13
 1 10.01.2000,HAM,FRA,XXX,ZZZ,105  -- 103

在值之前带有-的列是我期望的平均值。 如您所见,此示例有点复杂。仅对FLIGHT_DATE分组是不够的。必须有其他可明确识别的列。现在还必须考虑使用ARRIVAL_RUNWAY,DEPARTURE_RUNWAY,DEPARTURE_AIRPORT和ARRIVAL_AIRPORT才能正确计算(否则我错了吗?)

例如,在2000年1月1日,从BOG到FRA会得到nan,因为该航班没有至少3次历史航班。

但是2000年3月1日从BOG飞往FRA的航班有一个平均值,因为最后3个航班(2000年1月1日,2000年1月1日和2000年1月2日)。

否则,请查看具有HAM,FRA,XXX,ZZZ的航班以及具有HAM,FRA,XXX,YYY的航班,然后比较平均值,然后一切都应该清楚。

我尝试过:

dfTestB = pd.read_csv("Example2.csv")
dfTestB["FLIGHT_DATE"] = pd.to_datetime(dfTestB["FLIGHT_DATE"],format='%d.%m.%Y')
dfTestB = dfTestB.groupby(['FLIGHT_NUMBER','DEPARTURE_RUNWAY','ARRIVAL_RUNWAY']).apply(lambda x: x.set_index(['FLIGHT_DATE']).resample('1D').first())
df2 = dfTestB.groupby(level=0)['FLIGHT_DURATION'].apply(lambda x: x.shift().rolling(min_periods=3,window=3).mean()).reset_index(name='Value_Average_Past_3_days')
res = pd.merge(dfTestB, df2, on=['FLIGHT_NUMBER', 'FLIGHT_DATE'], how='left')

但是那不起作用...我该如何解决?

1 个答案:

答案 0 :(得分:0)

您的“分组”列似乎是['FLIGHT_NUMBER', 'DEPARTURE_AIRPORT', 'ARRIVAL_RUNWAY']

groupbyrolling.mean分别位于它们的每一个上,因此您可以移动结果以有效地采用前三行的滚动平均值。我找不到一种容易的方法来滚动以其他方式排除当前行的值。

import pandas as pd

gcols = ['FLIGHT_NUMBER', 'DEPARTURE_AIRPORT', 'ARRIVAL_RUNWAY']
df['result'] = pd.concat([gp.rolling(window=3, min_periods=3).mean().shift(1) 
                          for _, gp in df.groupby(gcols).FLIGHT_DURATION])

输出:(某些列被抑制)

    FLIGHT_NUMBER FLIGHT_DATE DEPARTURE_AIRPORT ARRIVAL_RUNWAY  result
0               1  01.01.2000               HAM            YYY     NaN
1               1  02.01.2000               HAM            YYY     NaN
2               1  03.01.2000               HAM            YYY     NaN
3               1  04.01.2000               HAM            ZZZ     NaN
4               1  05.01.2000               HAM            YYY    12.0
5               1  06.01.2000               HAM            ZZZ     NaN
6               9  01.01.2000               BOG            YYY     NaN
7               1  07.01.2000               HAM            ZZZ     NaN
8               9  01.01.2000               BOG            YYY     NaN
9               9  02.01.2000               BOG            YYY     NaN
10              9  03.01.2000               BOG            YYY  1002.0
11              1  08.01.2000               HAM            ZZZ   102.0
12              1  09.01.2000               HAM            YYY    13.0
13              1  10.01.2000               HAM            ZZZ   103.0