熊猫date_range freq ='BAS-JUL'不在该月的第一天

时间:2019-03-20 13:32:16

标签: python pandas

我正在用会计年度范围标记交易数据。例如,2018-2019会计年度的日期范围为7/1/2018-6/30/2019。由于某种原因,当我运行以下代码时,发生在2018年7月1日(会计年度的第一天)的任何交易都将其标记为2017年至2018年会计年度。还提供了样本数据。

data = [['Start 17-18 Fiscal', '7/1/2017'], ['End 17-18 Fiscal', '6/30/2018'], ['Start 18-19 Fiscal', '7/1/2018'], 
        ['End 18-19 Fiscal', '6/30/2019'], ['Start 19-20 Fiscal', '7/1/2019'], ['End 19-20 Fiscal', '6/30/2020']]
df = pd.DataFrame(data, columns=['Correct Fiscal', 'Date'])

df['Date'] = pd.to_datetime(df['Date'])
y_max = df['Date'].dt.year.max() + 1
y_min = df['Date'].dt.year.min() - 1
labels = [str(x) + ' - ' + str(x+1) for x in np.arange(y_min, y_max, 1)]
df['pay_period'] = pd.cut(df.Date, pd.date_range(str(y_min), str(y_max+1), freq='BAS-JUL'), right=False, labels=labels)

此外,如果您查看2019年至2020财政年度的样本数据,两者均按预期标记。下面是输出。

       Correct Fiscal       Date   pay_period
0  Start 17-18 Fiscal 2017-07-01  2016 - 2017
1    End 17-18 Fiscal 2018-06-30  2017 - 2018
2  Start 18-19 Fiscal 2018-07-01  2017 - 2018
3    End 18-19 Fiscal 2019-06-30  2018 - 2019
4  Start 19-20 Fiscal 2019-07-01  2019 - 2020
5    End 19-20 Fiscal 2020-06-30  2019 - 2020

更新的解决方案

因此,我能够解决此问题并将代码减少到仅这两行:

period_end = pd.to_datetime(df.Date).apply(pd.Period, freq='A-JUN')
df['fiscal_p'] = (period_end - 1).astype(str) + ' - ' + period_end.astype(str)

也感谢Dan提供功能答案。我可以肯定他的回答也可以。

1 个答案:

答案 0 :(得分:1)

我认为问题出在您的“标签”行,而不是日期范围频率。标签列表可确保第一行被标记为“ 2016 -2017”,根据您的输入,这是不正确的。

这是使用简单函数获取所需输出的另一种方法:

data = [['Start 17-18 Fiscal', '7/1/2017'], ['End 17-18 Fiscal', '6/30/2018'], ['Start 18-19 Fiscal', '7/1/2018'], 
        ['End 18-19 Fiscal', '6/30/2019'], ['Start 19-20 Fiscal', '7/1/2019'], ['End 19-20 Fiscal', '6/30/2020']]
df = pd.DataFrame(data, columns=['Correct Fiscal', 'Date'])

df['Date'] = pd.to_datetime(df['Date'])

def find_pay_period(date):
    if date.month == 7:
        end_year = date.year + 1
    elif date.month == 6:
        end_year = date.year
    else:
        return 'undefined'

    return f'{end_year - 1} - {end_year}'

df['pay_period'] = df['Date'].apply(find_pay_period)

哪个给出以下输出:

       Correct Fiscal       Date   pay_period
0  Start 17-18 Fiscal 2017-07-01  2017 - 2018
1    End 17-18 Fiscal 2018-06-30  2017 - 2018
2  Start 18-19 Fiscal 2018-07-01  2018 - 2019
3    End 18-19 Fiscal 2019-06-30  2018 - 2019
4  Start 19-20 Fiscal 2019-07-01  2019 - 2020
5    End 19-20 Fiscal 2020-06-30  2019 - 2020