Python Dataframe:根据月份获取替代日期?

5 python datetime numpy dataframe pandas

我有 df 列 salary_day

            salary_day
    0       thursday
    1       friday
Run Code Online (Sandbox Code Playgroud)

我正在尝试为每一天提供替代日期。

为了 May 2020

7,14,21,28 五月的星期四: 五月的星期五: 1,8,15,22,29

本月替代周四和周五的预期产量May

df

salary_day        req_dates
thursday           7,21 
friday           1,15,29
Run Code Online (Sandbox Code Playgroud)

对于June 2020

六月的星期四 : 六月的 4,11,18,25 星期五 : 5,12,19,26

由于五月有五个星期五,六月的第一个星期五不是替代日,应排除在外,而应考虑12,26。

本月替代周四和周五的预期产量June

df

salary_day        req_dates
thursday           4,18
friday             12,26



Run Code Online (Sandbox Code Playgroud)

编辑 1:适用于所有工作日

五月

      salary_day        req_dates
0     Monday            4,18
1     Tuesday           5,19
2     Wednesday         6,20
3     Thursday          7,21
4     Friday           1,15,29 
5     Saturday         2,16,30 
6     Sunday           3,17,31
Run Code Online (Sandbox Code Playgroud)

Erf*_*fan 2

我认为最干净、最通用的方法是创建一个包含指定年份所有日期的帮助表。并创建额外的列:month, day_name, day.

然后检查哪些day_namesdf['salary_day]`中。

之后,我们day通过以下方式检查是否不均匀:day % 2 > 0

最后我们通过以下方式GroupBy.agg加入字符串:day,

# create salary days to get altnerative days
days = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday']
df = pd.DataFrame({'salary_day': days})

START_MONTH = 5
YEAR = 2020

def create_dates(y, month_start):
    dates = pd.date_range(f'{y}-{str(month_start).zfill(2)}-01', f'{y}-12-31')
    dates = pd.DataFrame({'dates': dates})
    dates['month'] = dates['dates'].dt.month
    dates['day_name'] = dates['dates'].dt.day_name().str.lower()
    dates['day'] = dates['dates'].dt.day
    return dates


def get_alternative_dates(salary_days, y, month_start):
    df_dates = create_dates(y, month_start)

    m = df_dates['day_name'].isin(salary_days)

    months = df_dates[m].copy()
    months['day'] = months['day'].astype(str)
    months['rank_days'] = months.groupby('day_name')['day'].cumcount().add(1)

    months = months[months['rank_days'].mod(2).ne(0)]
    df_final = months.groupby(['month', 'day_name'])['day'].agg(','.join).reset_index()

    return df_final

get_alternative_dates(df['salary_day'], YEAR, START_MONTH)
Run Code Online (Sandbox Code Playgroud)

输出

    month  day_name      day
0       5    friday  1,15,29
1       5  thursday     7,21
2       6    friday    12,26
3       6  thursday     4,18
4       7    friday    10,24
5       7  thursday  2,16,30
6       8    friday     7,21
7       8  thursday    13,27
8       9    friday     4,18
9       9  thursday    10,24
10     10    friday  2,16,30
11     10  thursday     8,22
12     11    friday    13,27
13     11  thursday     5,19
14     12    friday    11,25
15     12  thursday  3,17,31
Run Code Online (Sandbox Code Playgroud)