python - 在熊猫中的非连续值上应用滚动窗口
问题描述
我需要通过将滚动窗口应用于数据框中不相邻的值来计算具有给定结构的数据框的新列。
我的数据框由以下内容定义:
df = pd.DataFrame([
{'date': date(2019,1,1), 'id': 1, 'value': 1},
{'date': date(2019,1,1), 'id': 2, 'value': 10},
{'date': date(2019,1,1), 'id': 3, 'value': 100},
{'date': date(2019,1,2), 'id': 1, 'value': 2},
{'date': date(2019,1,2), 'id': 2, 'value': 20},
{'date': date(2019,1,2), 'id': 3, 'value': 200},
{'date': date(2019,1,3), 'id': 1, 'value': 3},
{'date': date(2019,1,3), 'id': 2, 'value': 30},
{'date': date(2019,1,3), 'id': 3, 'value': 300},
{'date': date(2019,1,6), 'id': 1, 'value': 4},
{'date': date(2019,1,6), 'id': 2, 'value': 40},
{'date': date(2019,1,6), 'id': 3, 'value': 400},
])
df=df.set_index(['date', 'id'], drop=False).sort_index()
这给出了 df 看起来像这样:
date id value
date id
--------------+--------------------------
2019-01-01 1 | 2019-01-01 1 1
2 | 2019-01-01 2 10
3 | 2019-01-01 3 100
2019-01-02 1 | 2019-01-02 1 2
2 | 2019-01-02 2 20
3 | 2019-01-02 3 200
2019-01-03 1 | 2019-01-03 1 3
2 | 2019-01-03 2 30
3 | 2019-01-03 3 300
2019-01-06 1 | 2019-01-06 1 4
2 | 2019-01-06 2 40
3 | 2019-01-06 3 400
我想测量每个id从一天(给定)一天到下一天的列值变化。所以对于从to的变化是,从to是。id==1
2019-01-01
2019-01-02
(2-1) / 1 = 2
2019-01-03
2019-01-06
(4-3) / 3 = 0.333
如果我像这样重组 df 以便所有值彼此相邻,我可以计算所需的列:
restructured = df.reset_index(drop=True).set_index(['date']).sort_index()
df1 = restructured.groupby('id').rolling(2).apply(lambda x: (x.max()-x.min())/x.min(), raw=False)
在列value中产生所需的值:
id value
id date
---------------+--------------------
1 2019-01-01 | NaN NaN
2019-01-02 | 0.0 1.000000
2019-01-03 | 0.0 0.500000
2019-01-06 | 0.0 0.333333
2 2019-01-01 | NaN NaN
2019-01-02 | 0.0 1.000000
2019-01-03 | 0.0 0.500000
2019-01-06 | 0.0 0.333333
3 2019-01-01 | NaN NaN
2019-01-02 | 0.0 1.000000
2019-01-03 | 0.0 0.500000
2019-01-06 | 0.0 0.333333
如何将此列加入/合并到原始结构中的 df 或以另一种方式计算值,以便生成的数据框如下所示(第一个 df 添加列change_pct):
date id value change_pct
date id
--------------+---------------------------------
2019-01-01 1 | 2019-01-01 1 1 NaN
2 | 2019-01-01 2 10 NaN
3 | 2019-01-01 3 100 NaN
2019-01-02 1 | 2019-01-02 1 2 1.000000
2 | 2019-01-02 2 20 1.000000
3 | 2019-01-02 3 200 1.000000
2019-01-03 1 | 2019-01-03 1 3 0.500000
2 | 2019-01-03 2 30 0.500000
3 | 2019-01-03 3 300 0.500000
2019-01-06 1 | 2019-01-06 1 4 0.333333
2 | 2019-01-06 2 40 0.333333
3 | 2019-01-06 3 400 0.333333
解决方案
IIUC,这可能更简单。
df['change_pct']=df.groupby('id')['value'].pct_change()
为此,请勿运行此df=df.set_index(['date', 'id'], drop=False).sort_index()
. 只需直接在您的 df 上运行上述行。
输出
date id value change_pct
0 2019-01-01 1 1 NaN
1 2019-01-01 2 10 NaN
2 2019-01-01 3 100 NaN
3 2019-01-02 1 2 1.000000
4 2019-01-02 2 20 1.000000
5 2019-01-02 3 200 1.000000
6 2019-01-03 1 3 0.500000
7 2019-01-03 2 30 0.500000
8 2019-01-03 3 300 0.500000
9 2019-01-06 1 4 0.333333
10 2019-01-06 2 40 0.333333
11 2019-01-06 3 400 0.333333
推荐阅读
- javascript - 如何将 Internet 上的 JSON 文件中的数据显示为我网站上的 HTML?
- c++ - 为什么在函数中使用静态变量会使其运行速度变慢?
- uwp - 将 UWP 部署到远程设备
- ruby-on-rails - 创建了一个空记录,我该如何解决这个问题?
- javascript - 修正了一些语法
- python - 通过 Pandas 将大数据流式传输到 csv
- javascript - 您如何使用带有令牌身份验证的浏览器获取来发出 API 请求
- react-native - 使用 React Native Firebase 时如何远程调试 JS
- python - 扁平化 HTML 代码,使用树形结构分隔符
- java - XGetInputFocus 的正确 JNA 映射是什么