pandas 在Python中检查是否是月底

cvxl0en2  于 12个月前  发布在  Python
关注(0)|答案(8)|浏览(88)

我正在编写代码以获取去年的数据。我想像这样舍入较早的日期:如果是2015年7月14日,我需要2014年8月1日至2015年7月14日的数据

df = pd.read_csv('MyData.csv') 
df['recvd_dttm'] = pd.to_datetime(df['recvd_dttm'])
range_max = datetime.datetime.now() 
range_min = range_max - pd.tseries.offsets.DateOffset(years=1)+ pd.tseries.offsets.MonthEnd(1) + pd.tseries.offsets.DateOffset(days=1)
if datetime.datetime.now() == is_month_end:

# take slice with final week of data
df = df[(df['recvd_dttm'] >= range_min) & 
               (df['recvd_dttm'] <= range_max)]

字符串
我的问题是,当它是2015年7月31日,我的代码去到 * 下 * 个月结束,基本上削减了整整一个月。
我正在尝试创建一个for循环来解决这个问题。
如果是月底:

range_min = range_max - pd.tseries.offsets.DateOffset(years=1)


否则:

range_min = range_max - pd.tseries.offsets.DateOffset(years=1)+ pd.tseries.offsets.MonthEnd(1) + pd.tseries.offsets.DateOffset(days=1)


如何告诉python检查月末?MonthEnd只是一个offset函数。

xiozqbni

xiozqbni1#

我们可以避免使用只利用datetime的短函数来导入calendar模块。
如果明天的月份和今天的月份不一样,那么这意味着今天是当前月份的最后一天。

import datetime 
def end_of_month(dt):
    todays_month = dt.month
    tomorrows_month = (dt + datetime.timedelta(days=1)).month
    return tomorrows_month != todays_month

字符串
现在,针对您的特定用例:

now = datetime.datetime.now()
if end_of_month(now):
    range_min = range_max - pd.tseries.offsets.DateOffset(years=1)
else: 
    range_min = range_max - pd.tseries.offsets.DateOffset(years=1) +pd.tseries.offsets.MonthEnd(1) + pd.tseries.offsets.DateOffset(days=1)

6tdlim6h

6tdlim6h2#

我只是使用calendar模块的monthrange方法来查找该月的最后一天:

def check_if_last_day_of_week(date):
        import datetime
        import calendar
        #  calendar.monthrange return a tuple (weekday of first day of the 
        #  month, number  
        #  of days in month)
        last_day_of_month = calendar.monthrange(date.year, date.month)[1]
        # here i check if date is last day of month
        if date == datetime.date(date.year, date.month, last_day_of_month):
            return True
        return False

>>> date = datetime.date(2018, 12, 31)
>>> check_if_last_day_of_week(date)
True

字符串

slsn1g29

slsn1g293#

如果第二天是另一个月,那就意味着这是一个月的最后一天。

def check_if_last_day_of_month(to_date):
    delta = datetime.timedelta(days=1)
    next_day = to_date + delta

    return to_date.month != next_day.month

字符串

xqnpmsa8

xqnpmsa84#

我使用的是Pandas,我不想包含另一个库,所以我用这个来检查是否是一个月的最后一天和一年的最后一天:

import pandas as pd

my_date = '31-12-2021'

current_data = pd.to_datetime(my_date, format='%d-%m-%Y')
current_month = current_data.month
current_year = current_data.year

following_day = current_data + pd.DateOffset(1)
tomorrows_month = following_day.month
tomorrows_year = following_day.year

is_last_day_of_month = True if tomorrows_month != current_month else False
is_last_day_of_year = True if tomorrows_year != current_year else False

字符串

yshpjwxd

yshpjwxd5#

下面是一个纯python的方法,它也考虑到了闰年的二月:

# total days in every month during non leap years
M_DAYS = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

def isleap(year):
    """Return True for leap years, False for non-leap years."""
    return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)

def days_in_month(year, month):
    """Returns total number of days in a month accounting for leap years."""
    return M_DAYS[month] + (month == 2 and isleap(year))

def is_monthend(ref_date):
    """Checks whether a date is also a monthend"""
    return ref_date.day == days_in_month(ref_date.year, ref_date.month)

字符串

a0zr77ik

a0zr77ik6#

好吧,我是这样做的。找到BryanOakley建议的日历模块,并做了这个循环。它检查当前日期,并检查它是否与该月的最后一天相同,并相应地选择range_min。

if datetime.datetime.now().day == calendar.monthrange(date.year, date.month)[1]:
    range_min = range_max - pd.tseries.offsets.DateOffset(years=1)+ pd.tseries.offsets.DateOffset(days=1)
else:
    range_min = range_max - pd.tseries.offsets.DateOffset(years=1)+ pd.tseries.offsets.MonthEnd(1) + pd.tseries.offsets.DateOffset(days=1)

字符串

jaql4c8m

jaql4c8m7#

import datetime
def find_curr_month_end_date(curr_date):
    if(curr_date.month != 12):
        next_month_first_date= curr_date.replace(day=1).replace(month=curr_date.month+1)
    else:
        next_month_first_date= curr_date.replace(day=1).replace(month=1).replace(year=curr_date.year+1)

    curr_month_end_date = next_month_first_date - datetime.timedelta(days=1)

    return curr_month_end_date

curr_date = datetime.datetime.today() 
# or curr_date = datetime.datetime.strptime("2020-12-16","%Y-%m-%d")
curr_month_end_date = 
find_curr_month_end_date(curr_date)

字符串

o2g1uqev

o2g1uqev8#

这里有一个简短的函数来完成这个任务。它需要dateutil模块,这样你就可以做相对日期的计算。

import datetime
from dateutil.relativedelta import relativedelta

def lastyear_period_start(current_date):
    last_year = current_date - relativedelta(months=11)
    return datetime.date(last_year.year, last_year.month, 1)

字符串
它可以这样使用:

dates = [
    datetime.datetime(2010, 2, 27),
    datetime.datetime(2011, 2, 27),
    datetime.datetime(2012, 2, 27),
    datetime.datetime(2013, 2, 27),
    datetime.datetime(2014, 2, 27),
    datetime.datetime(2010, 7, 27),
    datetime.datetime(2011, 7, 27),
    datetime.datetime(2012, 7, 27),
    datetime.datetime(2013, 7, 27),
    datetime.datetime(2014, 7, 27),
    datetime.datetime(2015, 7, 14),
    datetime.datetime(2015, 7, 31),
    datetime.datetime(2011, 2, 28),
    datetime.datetime(2012, 2, 29),
    datetime.datetime(2013, 2, 28),
]

for d in dates:
    print d, lastyear_period_start(d)


这将打印以下内容:

2010-02-27 00:00:00 2009-03-01
2011-02-27 00:00:00 2010-03-01
2012-02-27 00:00:00 2011-03-01
2013-02-27 00:00:00 2012-03-01
2014-02-27 00:00:00 2013-03-01
2010-07-27 00:00:00 2009-08-01
2011-07-27 00:00:00 2010-08-01
2012-07-27 00:00:00 2011-08-01
2013-07-27 00:00:00 2012-08-01
2014-07-27 00:00:00 2013-08-01
2015-07-14 00:00:00 2014-08-01
2015-07-31 00:00:00 2014-08-01
2011-02-28 00:00:00 2010-03-01
2012-02-29 00:00:00 2011-03-01
2013-02-28 00:00:00 2012-03-01


在这个函数中,我们做了两个简单的步骤

  • 第一个月

首先我们根据传递给函数的日期找出11个月前的日期

  • return datetime.date(last_year.year, last_year.month, 1)

然后我们在那个月的第一天回来。
在上面的输出中,你可以看到这也解释了闰年。

相关问题