熊猫填充日期



我有以下数据帧,日期对应季度期间,金额(以及为了简化而没有显示的其他列)对应于关联的id分组。日期对每个id都是唯一的。

import pandas as pd
from numpy import nan
d = {'id': ['a', 'a', 'a', 'b', 'b'], 'date': ['2020-09-30', '2020-06-30', '2020-03-31', 
'2020-09-30', '2020-06-30'], 'amount': [1, 2, nan , 5, nan]}
df = pd.DataFrame(data=d)
df['date'] = pd.to_datetime(df['date'])
df
id        date       amount
0     a     2020-09-30       1
1     a     2020-06-30       2
2     a     2020-03-31       
3     b     2020-09-30       5
4     b     2020-06-30     

我想将季度开始的时间延长到过去的一个设置的开始季度日期,以便每个id的季度开始和存在于相同的日期。在本例中,数据应该从2019-12-31开始,如果缺少行,则应该填充中间的任何四分之一。

我想根据最近的现值回填缺失的值(如金额)。

输出如下所示:

id        date       amount
a     2020-09-30       1
a     2020-06-30       2
a     2020-03-31       2
a     2019-12-31       2
b     2020-09-30       5
b     2020-06-30       5
b     2020-03-31       5     
b     2019-12-31       5   

做这件事最好的方法是什么?

您需要从2019-12-31开始每三个月定义一个新的时间范围,并重新索引您的数据框架。然后用反向填充bfill方法填充NaN值。请看下面带注释的代码。

import pandas as pd
# Create the DataFrame according to your question
d = {'id': ['a', 'a', 'a', 'b', 'b'], 'date': ['2020-09-30', '2020-06-30', '2020-03-31', 
'2020-09-30', '2020-06-30'], 'amount': [1, 2, None, 5, None]}
df = pd.DataFrame(data=d)
# Transform date to datetime column
df['date'] = pd.to_datetime(df['date'])
# Set multiindex to (id, date) as they are the "unique keys" of your amount values
df.set_index(['id', 'date'], inplace=True)
# Define new period for the datetime index (every 3 months)
index = pd.date_range('2019-12-31', '2020-09-30', freq='3M')
# Reindex the Dataframe and fill NaNs with a backward method
print(df.reindex(pd.MultiIndex.from_product([df.index.get_level_values(0).unique(), index])).fillna(method='bfill'))

# Output
#                amount
# id                   
# a  2019-12-31     2.0
#    2020-03-31     2.0
#    2020-06-30     2.0
#    2020-09-30     1.0
# b  2019-12-31     5.0
#    2020-03-31     5.0
#    2020-06-30     5.0
#    2020-09-30     5.0

注意:设置包括id列的多索引是必要的,因为你想重新采样你的日期,而不合并idab

pyjanitor提供的完整函数为暴露缺失的行提供了一个抽象:

# pip install pyjanitor
import pandas as pd
import numpy as np
# create a mapping of the new dates
# reusing @scandav's index variable
index = pd.date_range('2019-12-31', '2020-09-30', freq='3M')
index = dict(date = index)
(df.complete('id', index)
.sort_values(['id', 'date'], ascending = [True, False])
.ffill(downcast = 'infer')
) 
id       date  amount
0  a 2020-09-30       1
1  a 2020-06-30       2
2  a 2020-03-31       2
5  a 2019-12-31       2
3  b 2020-09-30       5
4  b 2020-06-30       5
7  b 2020-03-31       5
6  b 2019-12-31       5

相关内容

  • 没有找到相关文章

最新更新