有没有一种快速的方法可以检查一个日期是否在一个日期列表的n天内(比如7天)

2024-05-15 00:46:11 发布

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

我正在使用以下数据集:

^{tb1}$

和一个列表holidays = ['2016-01-01','2016-01-18'....'2017-11-23','2017-12-25']

目标:创建一列,指示特定日期是否在列表中任何假日的+-7天内

模拟输出:

^{tb2}$

我正在处理大量的日期记录,因此试图找到一种快速(最优化)的方法来实现这一点

我当前的解决方案:

我想快速实现这一点的一种方法是创建另一个列表,其中只包含我所需持续时间(比如2年)的唯一日期。通过这种方式,我可以使用2 for loops实现一个简单的解决方案,以检查某个日期是否在假期的+-7天内,并且不会计算太多,因为两个列表都相对较小(730个唯一日期和假期列表中的约20个日期)。 一旦我有了我想要的日期列表,我所要做的就是在我的“日期”列上运行一次检查,看看该日期是否是我创建的新列表的一部分。但是,有什么建议可以更快地做到这一点吗


Tags: 数据方法目标列表for方式记录holidays
3条回答

试试这个:

示例:

import pandas as pd
df = pd.DataFrame({'Date': {0: '2016-01-04',
  1: '2016-01-05',
  2: '2016-01-06',
  3: '2016-01-07',
  4: '2016-01-08'}})

代码:

def get_date_range(holidays):
    h = [pd.to_datetime(x) for x in holidays]
    h = [pd.date_range(x - pd.DateOffset(6), x + pd.DateOffset(6)) for x in h]
    h = [x.strftime('%Y-%m-%d') for y in h for x in y]
    return h

df['Within a week of Holiday'] = df['Date'].isin(get_date_range(holidays))*1

结果:

Out[141]: 
0    1
1    1
2    1
3    1
4    0
Name: Within a week of Holiday, dtype: int32

制作一个function+- 7天计算日期,并检查计算日期是否在节假日,因此返回TrueelseFalse并将该函数应用于Data frame

import datetime
import pandas as pd
holidays = ['2016-01-01','2016-01-18','2017-11-23','2017-12-25']
def holiday_present(date):
    date = datetime.datetime.strptime(date, '%Y-%m-%d')
    for i in range(-7,7):
        datte = (date - datetime.timedelta(days=i)).strftime('%Y-%m-%d')
        if datte in holidays:
            return True
    return False

data = {
    "Date":[
"2016-01-04",
"2016-01-05",
"2016-01-06",
"2016-01-07",
"2016-01-08"]
}
df= pd.DataFrame(data)
df["Within a week of Holiday"] = df["Date"].apply(holiday_present).astype(int)

输出:

    Date    Within a week of Holiday
0   2016-01-04  1
1   2016-01-05  1
2   2016-01-06  1
3   2016-01-07  1
4   2016-01-08  0

将假日转换为数据帧,然后^{}允许6天:

new_df = pd.merge_asof(df, holidays, left_on='Date', right_on='Holiday',
                       tolerance=pd.Timedelta(days=6))
new_df['Holiday'] = np.where(new_df['Holiday'].notnull(), 1, 0)
new_df = new_df.rename(columns={'Holiday': 'Within a week of Holiday'})

完整的工作示例:

import numpy as np
import pandas as pd

holidays = pd.DataFrame(pd.to_datetime(['2016-01-01', '2016-01-18']),
                        columns=['Holiday'])

df = pd.DataFrame({
    'Date': ['2016-01-04', '2016-01-05', '2016-01-06', '2016-01-07',
             '2016-01-08']
})
df['Date'] = pd.to_datetime(df['Date'])

new_df = pd.merge_asof(df, holidays, left_on='Date', right_on='Holiday',
                       tolerance=pd.Timedelta(days=6))
new_df['Holiday'] = np.where(new_df['Holiday'].notnull(), 1, 0)
new_df = new_df.rename(columns={'Holiday': 'Within a week of Holiday'})
print(new_df)

new_df

        Date  Within a week of Holiday
0 2016-01-04                         1
1 2016-01-05                         1
2 2016-01-06                         1
3 2016-01-07                         1
4 2016-01-08                         0

或者将Holdiays转换为np datetime数组,然后对“Date”列进行^{}减法,将abs与7天进行比较,查看是否存在^{}匹配项:

holidays = np.array(['2016-01-01', '2016-01-18']).astype('datetime64')

df['Within a week of Holiday'] = (
        abs(df['Date'].values - holidays[:, None]) < pd.Timedelta(days=7)
).any(axis=0).astype(int)

完整的工作示例:

import numpy as np
import pandas as pd

holidays = np.array(['2016-01-01', '2016-01-18']).astype('datetime64')

df = pd.DataFrame({
    'Date': ['2016-01-04', '2016-01-05', '2016-01-06', '2016-01-07',
             '2016-01-08']
})
df['Date'] = pd.to_datetime(df['Date'])

df['Within a week of Holiday'] = (
        abs(df['Date'].values - holidays[:, None]) < pd.Timedelta(days=7)
).any(axis=0).astype(int)

print(df)

df

        Date  Within a week of Holiday
0 2016-01-04                         1
1 2016-01-05                         1
2 2016-01-06                         1
3 2016-01-07                         1
4 2016-01-08                         0

相关问题 更多 >

    热门问题