python - 在具有多个参数的 pandas 数据帧上应用滚动函数
问题描述
我正在尝试在 pandas 数据框上应用具有 3 年窗口的滚动功能。
import pandas as pd
# Dummy data
df = pd.DataFrame({'Product': ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'B'],
'Year': [2015, 2016, 2017, 2018, 2015, 2016, 2017, 2018],
'IB': [2, 5, 8, 10, 7, 5, 10, 14],
'OB': [5, 8, 10, 12, 5, 10, 14, 20],
'Delta': [2, 2, 1, 3, -1, 3, 2, 4]})
# The function to be applied
def get_ln_rate(ib, ob, delta):
n_years = len(ib)
return sum(delta)*np.log(ob[-1]/ib[0]) / (n_years * (ob[-1] - ib[0]))
预期的输出是
Product Year IB OB Delta Ln_Rate
0 A 2015 2 5 2
1 A 2016 5 8 2
2 A 2017 8 10 1 0.3353
3 A 2018 10 12 3 0.2501
4 B 2015 7 5 -1
5 B 2016 5 10 3
6 B 2017 10 14 2 0.1320
7 B 2018 14 20 4 0.2773
我努力了
df['Ln_Rate'] = df.groupby('Product').rolling(3).apply(lambda x: get_ln_rate(x['IB'], x['OB'], x['Delta']))
但这不起作用。
我找到了几个类似的帖子
将自定义滚动功能应用于数据框- 这个没有明确的答案
Pandas Rolling Apply custom - 这个没有多个参数
在滚动窗口上的 pandas 数据框上应用自定义函数- 这个有rolling.apply
... 但它不显示语法。
两者似乎都不是正确的。任何指向正确语法的指针将不胜感激。
解决方案
我通过重用滚动窗口解决了这个问题。
import numpy as np
WINDOW_SIZE = 3
rw = df.groupby('Product').rolling(WINDOW_SIZE)
df = df.assign(delta_sum=rw['Delta'].agg(np.sum).reset_index()['Delta'],
ib_first=rw['IB'].apply(lambda xs: xs[0]).reset_index()['IB'],
ob_last=rw['OB'].apply(lambda xs: xs[-1]).reset_index()['OB'])
df['ln_rate'] = df['delta_sum']*np.log(df['ob_last']/df['ib_first']) / (WINDOW_SIZE * (df['ob_last'] - df['ib_first']))
产生:
Product Year IB OB Delta delta_sum ib_first ob_last ln_rate
0 A 2015 2 5 2 NaN NaN NaN NaN
1 A 2016 5 8 2 NaN NaN NaN NaN
2 A 2017 8 10 1 5.0 2.0 10.0 0.335300
3 A 2018 10 12 3 6.0 5.0 12.0 0.250134
4 B 2015 7 5 -1 NaN NaN NaN NaN
5 B 2016 5 10 3 NaN NaN NaN NaN
6 B 2017 10 14 2 4.0 7.0 14.0 0.132028
7 B 2018 14 20 4 9.0 5.0 20.0 0.277259
重置索引是必要的,以将分组的 DataFrame 转换回其初始形状。
希望有帮助。
推荐阅读
- python - Errno 111:使用 Python 脚本连接到 Elasticsearch 时连接被拒绝
- ios - 从 UITableView 获取所有单元格
- html - 如何让项目符号点显示在 HTML 选项卡中
- angular - 为什么 mat-autocomplete 不显示搜索到的选项?
- python-3.7 - Python 3.7 上的 netCDF4 和 Basemap 包
- r - 通过通用标识符合并复杂的 data.frame 行
- google-cloud-platform - GCP PUB/SUB 允许不同的项目发布到一个主题
- c++ - 我将如何从 C++ 中的加密函数创建解密函数?
- python - Spyder 在新的 Conda 环境中启动时显示 I/O 错误
- javascript - 如果条件值取决于 sessionStorage,我如何使用 jest if 分支进行测试