pyspark 编写一个函数,生成从当前日期开始的过去n个月中每个月的最后几天的列表

vbopmzt1  于 2022-12-03  发布在  Spark
关注(0)|答案(3)|浏览(190)

我正在尝试创建从当前日期开始的过去n个月内每个月的最后几天的列表,但不包括当前月份
我尝试了不同的方法:

def last_n_month_end(n_months):
    """
    Returns a list of the last n month end dates
    """
    return [datetime.date.today().replace(day=1) - datetime.timedelta(days=1) - datetime.timedelta(days=30*i) for i in range(n_months)]

如果每个月只有30天,并且在databricks pyspark中也不工作,那么这个方法部分有效。它返回AttributeError: 'method_descriptor' object has no attribute 'today'
我还尝试了Generate a sequence of the last days of all previous N months with a given month中提到的方法

def previous_month_ends(date, months):
  year, month, day = [int(x) for x in date.split('-')]
  d = datetime.date(year, month, day)
  t = datetime.timedelta(1)
  s = datetime.date(year, month, 1)
  return [(x - t).strftime('%Y-%m-%d')
          for m in range(months - 1, -1, -1)
          for x in (datetime.date(s.year, s.month - m, s.day) if s.month > m else \
                    datetime.date(s.year - 1, s.month - (m - 12), s.day),)]

但我没有理解正确。
我也试探着:

df = spark.createDataFrame([(1,)],['id'])

days = df.withColumn('last_dates', explode(expr('sequence(last_day(add_months(current_date(),-3)), last_day(add_months(current_date(), -1)), interval 1 month)')))

我得到了最后三个月(9月,10月,11月),但他们都是30日,但10月有10月31日。然而,它给了我正确的最后几天,当我把超过3。
我想得到的是:(过去4个月的最后几天,不包括current_date的last_day)
daterange = ['2022-08-31','2022-09-30','2022-10-31','2022-11-30']

wwtsj6pe

wwtsj6pe1#

不确定这是不是最好的或最优的方法,但这做到了...
需要下面的包,因为datetime似乎没有任何东西来减去月,据我所知,没有硬编码的天数或周数。不确定,所以不要引用我的这一点...

软件包安装:

pip install python-dateutil

**编辑:**我这边有一个误解。我以为所有的日期都是必需的,而不仅仅是月底。无论如何,希望更新的代码可能会有帮助。仍然不是最优化的,但我想很容易理解。

# import datetime package
from datetime import date, timedelta
from dateutil.relativedelta import relativedelta

def previous_month_ends(months_to_subtract):
    # get first day of current month
    first_day_of_current_month = date.today().replace(day=1)
    print(f"First Day of Current Month: {first_day_of_current_month}")
    # Calculate and previous month's Last date
    date_range_list = [first_day_of_current_month - relativedelta(days=1)]
    cur_iter = 1
    while cur_iter < months_to_subtract:
        # Calculate First Day of previous months relative to first day of current month
        cur_iter_fdom = first_day_of_current_month - relativedelta(months=cur_iter)
        # Subtract one day to get the last day of previous month
        cur_iter_ldom = cur_iter_fdom - relativedelta(days=1)
        # Append to the list
        date_range_list.append(cur_iter_ldom)
        # Increment Counter
        cur_iter+=1
    return date_range_list

print(previous_month_ends(3))

用于计算2个日期之间的日期列表的函数:

1.计算当月的第一天。
1.计算开始日期和结束日期,然后遍历它们以获得日期列表。
1.我已经忽略了日期参数,因为我已经假设它将是当前日期。或者,它可以添加到您自己的代码,这应该工作完美。

# import datetime package
from datetime import date, timedelta
from dateutil.relativedelta import relativedelta

def gen_date_list(months_to_subtract):
    # get first day of current month
    first_day_of_current_month = date.today().replace(day=1)
    print(f"First Day of Current Month: {first_day_of_current_month}")
    start_date = first_day_of_current_month - relativedelta(months=months_to_subtract)
    end_date = first_day_of_current_month - relativedelta(days=1)
    print(f"Start Date: {start_date}")
    print(f"End Date: {end_date}")
    date_range_list = [start_date]
    cur_iter_date = start_date
    while cur_iter_date < end_date:
        cur_iter_date += timedelta(days=1)
        date_range_list.append(cur_iter_date)
        # print(date_range_list)
    return date_range_list

print(gen_date_list(3))

希望它有帮助...编辑/评论是受欢迎的-我正在学习自己...

xzlaal3s

xzlaal3s2#

from datetime import datetime, timedelta

def get_last_dates(n_months):
   '''
   generates a list of lastdates for each month for the past n months
   Param:
     n_months = number of months back
   '''
  last_dates = []  # initiate an empty list
  for i in range(n_months):
    last_dates.append((datetime.today() - timedelta(days=i*30)).replace(day=1) - timedelta(days=1))
  return last_dates

这样可以给予更准确的last_days

polkgigr

polkgigr3#

我只是想到了一个我可以使用的解决方案,因为我的上一个代码工作:

df = spark.createDataFrame([(1,)],['id'])

days = df.withColumn('last_dates', explode(expr('sequence(last_day(add_months(current_date(),-3)), last_day(add_months(current_date(), -1)), interval 1 month)')))

输入-4并删除不需要的last_date days.pop(0),它应该会给予所需的last_date列表。

相关问题