python - Pandas:过去 k 天的平均值
问题描述
我想计算最后 k 次出现的 (FLIGHT_DURATION) 的滚动平均值。相对于 FLIGHT_DATE 给出的顺序,最后一个表示最后一个。
就像我在以下示例中所做的那样:
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
如您所见,我添加了一个显示平均值的新列。至少需要 3 天。
问题:
现在我有一个更复杂的数据框:
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 现在也必须考虑正确计算(或者我错了吗?)
例如,在 01.01.2000 FROM BOG to FRA 得到一个 nan,因为该航班没有至少 3 个历史航班。
但是 03.01.2000 的 BOG 到 FRA 航班具有平均值,因为有 3 个末班航班(01.01.2000、01.01.2000 和 02.01.2000)。
否则查看带有 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')
但这不起作用...我该如何解决?
解决方案
您的“分组”列似乎是['FLIGHT_NUMBER', 'DEPARTURE_AIRPORT', 'ARRIVAL_RUNWAY']
groupby
并rolling.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
推荐阅读
- reactjs - reactjs flatlist 降序和升序不适用于下拉菜单
- google-smart-home - 恒温器触摸控制可用于一项操作,但不能用于另一项操作
- linux - 在第一次匹配时删除第 N 列中特定数字之前的所有字符而不是最后一个
- azure - Cosmos 存储过程中的 RequestEntityTooLarge
- verilog - 最高有效位的 32 位 OR 操作 Verilog 意外结果
- ssl-certificate - 关闭 SSL Cloudflare,无法通过 SSL Let's Enscrypt 访问网站
- azure - Azure AFD 到 AS 会话关联性问题
- mysql - 如何在 MySQL 中以最快的速度计算总行数 GROUP BY
- java - 生成自定义标识
- laravel - 方法 Illuminate\Database\Eloquent\Collection::save 不存在