python - 如何根据 id 和“原始日期”范围填充熊猫数据框?
问题描述
我有一个 DataFrame,其中有 1000 行和 100 列,我想在其中转发数据,但按 id 和原始数据(日期范围)分组。我所说的原始数据的意思是,如果我们有日期为 01/01/2020 的 id 1 的数据,但日期为 01/05/2020、02/02/2020 的空值,我想在 01/05 填写数据/2020 但不是 02/02/2020,因为 02/02/2020 不在 30 天内。当我们填充时,它会根据最后一个结果填充所有数据。
import pandas as pd
import numpy as np
res= pd.DataFrame({'id':[1,1,1,1,1,2,2],
'date':['01/01/2020','01/05/2020','02/03/2020','02/05/2020','04/01/2020','01/01/2020','01/02/2020'],
'result':[1.5,np.nan,np.nan,2.6,np.nan,np.nan,6.0]})
res['result1']= res.groupby(['id']).apply(lambda x: x.result.ffill()).reset_index(drop=True)
我得到的结果是:
id date result result1
0 1 01/01/2020 1.5 1.5
1 1 01/05/2020 NaN 1.5
2 1 02/03/2020 NaN 1.5
3 1 02/05/2020 2.6 2.6
4 1 04/01/2020 NaN 2.6
5 2 01/01/2020 NaN NaN
6 2 01/02/2020 6.0 6.0
我想要的是:
id date result result1
0 1 01/01/2020 1.5 1.5
1 1 01/05/2020 NaN 1.5
2 1 02/03/2020 NaN NaN
3 1 02/05/2020 2.6 2.6
4 1 04/01/2020 NaN NaN
5 2 01/01/2020 NaN NaN
6 2 01/02/2020 6.0 6.0
解决方案
你可以试试merge_asof
res['date']=pd.to_datetime(res['date'])
res = res.sort_values('date')
res1 = res.dropna(subset=['result']).rename(columns={'result':'result1'})
out = pd.merge_asof(res.reset_index(),res1 , by ='id', on ='date',tolerance = pd.Timedelta(30, unit='d'),direction = 'backward').sort_values('index')
Out[72]:
index id date result result1
0 0 1 2020-01-01 1.5 1.5
3 1 1 2020-01-05 NaN 1.5
4 2 1 2020-02-03 NaN NaN
5 3 1 2020-02-05 2.6 2.6
6 4 1 2020-04-01 NaN NaN
1 5 2 2020-01-01 NaN NaN
2 6 2 2020-01-02 6.0 6.0
推荐阅读
- vue.js - 如何将路径添加到“vue-cli-service lint”
- java - DLL JAVA调用嵌套DLL方法
- wikipedia - 将 Wikidata QID 映射到 Wikipedia CurID
- typescript - 如何为具有默认导出的模块创建 TSD?
- mysql - Mysql 触发 if 语句更新第二张表
- python - 不同的语法错误隐藏输出中的行
- reactjs - 父组件中的表单提交时如何使子组件更新
- xlc - 我该如何使用#include 来完成这项工作?直接放入代码中时效果很好
- c# - Blazor 子组件模板化/渲染片段问题
- node.js - 在 Fargate 中运行的 Node Web 应用程序在内存和 CPU 相对没有负担的负载下崩溃