我认为你不能用pandas 做到这一点。但是,您可以使用我在下面创建的名为 business_week 的矢量化函数(当我使用它时,我还为 business day 创建了一个)。这些函数说明闰年。此功能从您过去的月份/日期的第一天开始计算,而不是一周中的特定日期。请注意,一年有 52 个整周,并且根据闰年的不同,还有 1 或 2 天,因此 6 月 30 日将显示为周53,6 月 29 日也将显示为闰年。如果您希望它是 52,您可以简单地将 53 替换为 52。您必须传递以下参数:
- 要以日期时间格式导出工作日的列
- 开始月份
- 开始日
例如: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