大Pandas:计算金融周数

2024-05-16 19:26:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我有五年的金融相关数据。财政年度从7月1日开始,到6月30日结束。我想计算每个财政年度的财政周。我想对数据框的date列应用一些操作,这样当我编写类似df['date].dt.week的内容时,它应该返回财务周编号,而不是返回日历周编号。因此,我使用以下代码来执行所需的输出:

df['date'] = df['date'].apply(pd.Period,freq='W')
df['date'].dt.week

但这并没有产生预期的结果。有人能告诉我哪里出了错吗


Tags: 数据代码内容dfdatedt金融编号
2条回答

Series.dt.weekid已弃用。我没有遇到一个财政年度的星期。可能会将“开始周数”设置为从某个日期开始

在强制日期到日期时间之后,我会尝试以下方法

df.date.apply(lambda x: pd.Period(x,freq='D').week)

df['date'].dt.strftime("%W").astype(int)

我认为你不能用pandas来做这件事。但是,您可以使用我在下面创建的名为business_week的向量化函数(在我使用它的同时,我还为business day创建了一个)。这些函数用于闰年。此函数从您通过的月份/日期的第一天开始计算,而不是从一周中的特定日期开始计算。请注意,一年中有52个完整的星期,根据闰年的不同,还有1到2天的额外天数,因此6月30日将显示为第53周,6月29日也将显示为闰年。如果你想把53换成52,你可以简单地把53换成52。您必须传递以下参数:

  1. 要以datetime格式导出《商业周刊》的列
  2. 开始月份
  3. 开始一天

例如:df['week'] = business_week(df['date'], 7, 1)和下面的最小可复制示例:

df = pd.DataFrame({'date': 
{0: pd.Timestamp('2019-01-01 00:00:00'),
1: pd.Timestamp('2019-06-28 00:00:00'),
2: pd.Timestamp('2019-06-29 00:00:00'),
3: pd.Timestamp('2019-06-30 00:00:00'),
4: pd.Timestamp('2019-07-01 00:00:00'),
5: pd.Timestamp('2019-07-07 00:00:00'),
6: pd.Timestamp('2019-07-08 00:00:00'),
7: pd.Timestamp('2020-01-01 00:00:00'),
8: pd.Timestamp('2020-06-28 00:00:00'),
9: pd.Timestamp('2020-06-29 00:00:00'),
10: pd.Timestamp('2020-06-30 00:00:00'),
11: pd.Timestamp('2020-07-01 00:00:00'),
12: pd.Timestamp('2020-07-07 00:00:00'),
13: pd.Timestamp('2020-07-08 00:00:00')}})

def business_week(d, start_month, start_day):
    from datetime import datetime, timedelta
    y_int = d.dt.year
    y_str = y_int.astype(str)
    start_md = (datetime(2020, start_month, start_day) - timedelta(days=1)).strftime('%m-%d')
    start_ymd = pd.to_datetime(y_str + '-' + start_md)
    s = d.dt.dayofyear - start_ymd.dt.dayofyear
    m1 = s.mask(s < 1, 365 - abs(s))
    m2 = m1.mask((y_int % 4 == 0) & (d > start_ymd), m1 - 1)
    return np.where(y_int % 4 != 0, (m2 + 6) / 7, (m2 + 7) / 7).astype(int)


df['week'] = business_week(df['date'], 7, 1)
df
Out[1]: 
         date  week
0  2019-01-01    27
1  2019-06-28    52
2  2019-06-29    52
3  2019-06-30    53
4  2019-07-01     1
5  2019-07-07     1
6  2019-07-08     2
7  2020-01-01    27
8  2020-06-28    52
9  2020-06-29    53
10 2020-06-30    53
11 2020-07-01     1
12 2020-07-07     1
13 2020-07-08     2

另外,如果需要,可以使用类似的方法返回business_day

def business_day(d, start_month, start_day):
    from datetime import datetime, timedelta
    y_int = d.dt.year
    y_str = y_int.astype(str)
    start_md = (datetime(2020, start_month, start_day) - timedelta(days=1)).strftime('%m-%d')
    start_ymd = pd.to_datetime(y_str + '-' + start_md)
    s = d.dt.dayofyear - start_ymd.dt.dayofyear
    m1 = s.mask(s < 1, 365 - abs(s))
    m2 = m1.mask((y_int % 4 == 0) & (d <= start_ymd), m1 + 1)
    return m2


df['day'] = business_day(df['date'], 7, 1)
df
Out[1]: 
         date  day
0  2019-01-01  185
1  2019-06-28  363
2  2019-06-29  364
3  2019-06-30  365
4  2019-07-01    1
5  2019-07-07    7
6  2019-07-08    8
7  2020-01-01  185
8  2020-06-28  364
9  2020-06-29  365
10 2020-06-30  366
11 2020-07-01    1
12 2020-07-07    7
13 2020-07-08    8

相关问题 更多 >