python - 给定开始日期和结束日期,生成中间所有周的最有效方法是什么?

标签 python pandas pyspark

我有两列,“start_date”和“end_date”,它们可以是各种日期,从一天(日期之间没有差异)到相隔 18 个月。然而,我正在使用的 API 只需要 7 天的日期间隔,因此我想将用户提供的日期范围解析为每 7 天的唯一行(并且不超过提供的结束日期)。

我用 udf 成功实现了这一点,但我很好奇是否有一种我没有想到的更有效的方法。这是我开始使用的数据框:

foo   start_date   end_date
foo1  2017-08-01   2017-09-01

我把它改成了这样:

foo   start_date   end_date
foo1  2017-08-01   2017-08-07
foo1  2017-08-08   2017-08-14
foo1  2017-08-15   2017-08-21
foo1  2017-08-22   2017-08-28
foo1  2017-08-29   2017-09-01

这是我的代码。它可以工作,并且对于我的数据目的来说很好,因为我一次只能分割大约 40 行......但该解决方案感觉异常笨拙。我很好奇是否有更有效的方法。

def list_of_weeks(start,end):
  if start == end:
    return start
  else:
    start, end = datetime.strptime(start, '%Y-%m-%d'), datetime.strptime(end, '%Y-%m-%d')
    dates = [start]
    curr_date = start
    end = end - timedelta(7)
    while curr_date <= end:
      curr_date += timedelta(7)
      dates.append(curr_date)
    dates = ','.join([x.strftime('%Y-%m-%d') for x in dates])
    return dates

end = df.select('end_date').collect()[0][0]
end = datetime.strptime(end, '%Y-%m-%d')

list_of_weeks_udf = udf(list_of_weeks)
df = (df.withColumn('start_date', split(list_of_weeks_udf('start_date','end_date'), ','))
            .withColumn('start_date', explode('start_date'))
            .withColumn('start_date', to_date('start_date'))
            .withColumn('end_date', date_add('start_date', 6))
            .withColumn('end_date', when(col('end_date')>end, end.strftime('%Y-%m-%d')).otherwise(col('end_date'))))

最佳答案

这是使用pandas' date_range :

import pandas

start, end = '2017-08-01', '2017-09-01'
d1 = pandas.date_range(start=start, end=end, freq='7D')
d2 = d1.shift(6, freq='d')
# fix end date (make sure latest end_date it doesn't go over end_date)
d2 = list(d2)[:-1] + [min(d2[-1], pandas.Timestamp(end))]

df = pandas.DataFrame(data=dict(foo=['foo1']*len(d1), start_date=d1, end_date=d2), 
    columns=('foo', 'start_date', 'end_date'))

print(df.to_string(index=False))

打印:

foo start_date   end_date
foo1 2017-08-01 2017-08-07
foo1 2017-08-08 2017-08-14
foo1 2017-08-15 2017-08-21
foo1 2017-08-22 2017-08-28
foo1 2017-08-29 2017-09-01

顺便说一句,由于 index=False,理由似乎略有偏差,请参阅 this open pandas bug

关于python - 给定开始日期和结束日期,生成中间所有周的最有效方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48131816/

相关文章:

python - matplotlib.mlab 和 numpy.abs(numpy.fft.fft(data)) 中可用的模量谱结果之间的差异

python - 如何多次在 Pandas 数据框中添加特定行

python - 在 Pandas 数据框中一次更改一行

python - 使用 Pandas 计算增量列

python - "normalize"将句子的数据帧转换为更大的单词数据帧

python - 每张工作表有多个数据框,每个工作簿有多个工作表

python - Matplotlib basemap 多个形状动画异常: 'list' object has no attribute 'set_animated'

pyspark - 计算每个 pyspark RDD 分区中的元素数

pyspark - 如何将消息写入 AWS Glue 上的输出日志?

python - MATLAB打开带有savemat写的汉字的.mat文件时报错