首页 > 解决方案 > 给定具有特定年份的开始日期和结束日期,填充仅包含日期和月份的数据框的日期列的最佳方法是什么?

问题描述

我正在解析在文件名和文档中都有完整开始和结束日期的银行对帐单 PDF,但与交易相对应的实际条目仅包含日期和月份('%d %b')。以下是“日期”列的系列外观:

1           
2     24 Dec
3     27 Dec
4           
5           
6     30 Dec
7           
8     31 Dec
9           
10          
11     2 Jan
12          
13     3 Jan
14     6 Jan
15    14 Jan
16    15 Jan

我的开始日期和结束日期分别为 2013-12-23 和 2014-01-23。在给定开始和结束范围的情况下,使用正确的完整日期填充此系列/列的有效方法是什么?我希望任何现有日期将相同的日期转发到下一个日期,因此:

1           
2     24 Dec 2013
3     27 Dec 2013
4     27 Dec 2013 
5     27 Dec 2013 
6     30 Dec 2013
7     30 Dec 2013 
8     31 Dec 2013
9     31 Dec 2013 
10    31 Dec 2013     
11     2 Jan 2014
12     2 Jan 2014    
13     3 Jan 2014
14     6 Jan 2014
15    14 Jan 2014
16    15 Jan 2014

只要是日期时间格式,日期格式就无关紧要。我希望使用熊猫内部的东西,但我不知道要使用什么,现在检查开始和结束日期并根据日期适合范围的位置填写年份是最好的我'我想出了,但是必须在整个列上运行它是低效的。任何帮助/建议/提示将不胜感激,在此先感谢。

编辑:只是想补充一点,我希望有一个通用的程序解决方案,可以应用于任何开始/结束日期和交易集,而不仅仅是这个特定系列,尽管我认为这是一个很好的测试用例,因为它有年重叠。

EDIT2:发布此问题后,到目前为止我所拥有的是以下内容,这似乎不是非常有效,但似乎有效:

def add_year(date, start, end):
    if not date:
        return(np.NaN)
    else:
        test_date = "{} {}".format(date, start.year)
        test_date = datetime.strptime(test_date, '%d %b %Y').date()
        if start_date <= test_date <= end_date:
            return(test_date)
        else:
            return(datetime.strptime("{} {}".format(date, end.year), '%d %b %Y').date())

df['Date'] = df.Date.map(lambda date: add_year(date, start_date, end_date))
df.Date.ffill(inplace=True)

标签: pythonpandasdataframedatedatetime

解决方案


尝试:

df['Date']=df['Date'].replace('nan|NaN',float('NaN'),regex=True)
#convert string nan to actual NaN's
df['Date']=df['Date'].ffill()
#forword fill NaN's
c=df['Date'].str.contains('Dec') & df['Date'].notna()
#checking if Date column contain Dec
idx=df[c].index[-1]
#getting the index of last 'Date' where condition c satisfies
df.loc[:idx,'Date']=df.loc[:idx,'Date']+' 2013'
#adding 2013 to 'Date' upto last index of c
df.loc[idx+1:,'Date']=df.loc[idx+1:,'Date']+' 2014'
#adding 2014 to 'Date' from last index of c+1 upto last
df['Date']=pd.to_datetime(df['Date'])
#Finally converting these values to datetime

输出df

    Date
0   NaT
1   2013-12-24
2   2013-12-27
3   2013-12-27
4   2013-12-27
5   2013-12-30
6   2013-12-30
7   2013-12-31
8   2013-12-31
9   2013-12-31
10  2014-01-02
11  2014-01-02
12  2014-01-03
13  2014-01-06
14  2014-01-14
15  2014-01-15

推荐阅读