我知道如何使用带有 ffill 或 bfill 的 groupby 方法来估算缺失值。但我这里的问题是,我需要首先在“日期”列中找到最接近“分数”列中空值的日期,如果分数列中的值不为空,则用该值估算它。如果该值为空,我需要搜索另一个最近的日期。我可以遍历行并执行它,但是速度很慢。
这是一个数据示例:
df = pd.DataFrame(
{'cn': [1, 1, 1, 1, 2, 2, 2],
'date': ['01/10/2017', '02/09/2016', '02/10/2016','01/20/2017', '05/15/2019', '02/10/2016', '02/10/2017'],
'score': [np.nan, np.nan, 6, 5, 4, np.nan, 8]})
cn date score
0 1 01/10/2017 NaN
1 1 02/09/2016 NaN
2 1 02/10/2016 6
3 1 01/20/2017 5
4 2 05/15/2019 4
5 2 02/10/2016 NaN
6 2 02/10/2017 8.0
输出应该是
cn date score
0 1 01/10/2017 5
1 1 02/09/2016 6
2 1 02/10/2016 6
3 1 01/20/2017 5
4 2 05/15/2017 4
5 2 02/10/2016 8
6 2 02/10/2018 8
如何使用 groupby 方法和应用函数来实现?
请您参考如下方法:
使用pd.merge_asof 获取最接近匹配的Series 然后只是.fillna。有一些操作可以确保事情最终在索引上对齐。
import pandas as pd
df['date'] = pd.to_datetime(df.date)
s = (pd.merge_asof(
df.sort_values('date').reset_index(), # Full Data Frame
df.sort_values('date').dropna(subset=['score']), # Subset with valid scores
by='cn', # Only within `'cn'` group
on='date', direction='nearest' # Match closest date
)
.set_index('index')
.score_y)
df['score'] = df.score.fillna(s, downcast='infer')
输出:df
cn date score
0 1 2017-01-10 5
1 1 2016-02-09 6
2 1 2016-02-10 6
3 1 2017-01-20 5
4 2 2019-05-15 4
5 2 2016-02-10 8
6 2 2017-02-10 8
