如何在 pandas dataframe 中移动日期,参考包含工作日的特定列?

4

我想引用名为“Unloading point”的特定列,以便将我的日期映射到这些特定的工作日。因此,“Date”列中的日期应基于“Unloading point”进行映射。如果“Unloading point”列中没有数据,并且日期在周末,则应将其回滚到最近的工作日。我对pandas数据框架非常陌生。任何帮助将不胜感激。

日期 卸货点 预期输出
2021年5月30日 周一至周五 2021年5月31日
2021年6月11日 周一至周五 2021年6月11日
2021年6月5日 周四 2021年6月3日
2021年6月4日 周四 2021年6月3日
2021年5月27日 周四 2021年5月27日
2021年5月29日 周四 2021年5月27日
2021年5月29日 2021年5月28日
2021年6月6日 周一至周五 2021年6月7日
2021年6月1日 2021年6月1日
2021年5月29日 周二 2021年5月25日
2021年6月1日 2021年6月1日
2021年7月31日 周四 2021年7月29日
2021年6月1日 周三 2021年6月2日
2021年5月26日 周三 2021年5月26日
2021年6月14日 周一至周五 2021年6月14日
2021年5月27日 周一至周三 2021年5月26日
2021年6月15日 周一至周三 2021年6月15日
2021年5月22日 周二至周三 2021年5月19日
2021年6月10日 周一至周三 2021年6月10日
2021年6月24日 周二及周五 2021年6月22日

我不理解你的所有条件。你说如果有一个空的卸货点,就把日期改到某个工作日。但是如果卸货点已经满了,你会怎么做呢? - thomas
开始学习Python中的日历,你可以查看calendar - thomas
@thomas 如果卸货点为空,则应仅检查日期是否为工作日。如果日期落在周末,应回滚到最近的工作日。如果此列具有某些值,例如(TUE-WED),则日期应回滚到此列中引用的最近的B日,这里是(WED)。因此,如果日期是2021年5月22日(SAT),则应回滚到2021年5月19日(WED)。 - SamirJ
1个回答

0
为了回答这个问题,我们可以使用自定义工作日。这些对象的构造函数需要一个weekmask参数,其中包含被视为工作日的一周中的日期列表,例如"Mon Tue Wed"。还可以指定节假日。这些对象的工作原理类似于BusinessDay类,但具有按我们所需指定工作日的自由。
答案

关键在于为每一行创建一个CDay对象。

from pandas.tseries.offsets import CDay  # Same as CustomBusinessDay

# Make DimetimeIndex
df['date'] = pd.to_datetime(df['date'])
# Format the weekmask correctly
df['weekmask'] = df['weekmask'].str.replace('-', ' ').str.title()

def roll(s):
    # The default weekmask is Monday to Friday.
    cday = CDay(weekmask=s.weekmask) if s.weekmask else CDay()
    next_day = cday.rollforward(s.date)
    prev_day = cday.rollback(s.date)
    return next_day if next_day - s.date < s.date - prev_day else prev_day

df['roll'] = df.apply(roll, axis='columns')
结果
         date             weekmask       roll
0  2021-05-30  Mon Tue Wed Thu Fri 2021-05-31
1  2021-06-11  Mon Tue Wed Thu Fri 2021-06-11
2  2021-06-05                  Thu 2021-06-03
3  2021-06-04                  Thu 2021-06-03
4  2021-05-27                  Thu 2021-05-27
5  2021-05-29                  Thu 2021-05-27
6  2021-05-29                 None 2021-05-28
7  2021-06-06  Mon Tue Wed Thu Fri 2021-06-07
8  2021-06-01                 None 2021-06-01
9  2021-05-29                  Tue 2021-06-01
10 2021-06-01                 None 2021-06-01
11 2021-07-31                  Thu 2021-07-29
12 2021-06-01                  Wed 2021-06-02
13 2021-05-26                  Wed 2021-05-26
14 2021-06-14  Mon Tue Wed Thu Fri 2021-06-14
15 2021-05-27          Mon Tue Wed 2021-05-26
16 2021-06-15          Mon Tue Wed 2021-06-15
17 2021-05-22              Tue Wed 2021-05-19
18 2021-06-10          Mon Tue Wed 2021-06-09
19 2021-06-24              Tue Fri 2021-06-25

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接