【问题标题】:transform month to discrete time periods将月份转换为离散时间段
【发布时间】:2018-03-14 00:32:02
【问题描述】:

假设我有一个 datetime.date 格式的日期列表。我想将月份中的日期转换为离散(整数)期间。

即,

myList = [datetime.date(2015,02,08), datetime.date(2015,02,25), datetime.date(2015,05,03), datetime.date(2016,03,27)]

由于最小的年/月是 2015/02,因此该月等于 0。下个月 2015/03 将为 1,依此类推。直到上个月 2016/03 为 13。

我想要一个函数,我给它一个开始日期,然后它给我离散的月份。

即,

discretizeMo(start_date, date_of_interest)
discretizeMo('2012-02-01', '2013-01-01')

将返回 11,等等。

【问题讨论】:

    标签: python datetime


    【解决方案1】:

    好吧,既然你放弃了日期,那么通常的日期算术在这里就没有用了。最简单的解决方案是将年和月转换为比例:

    def discretizeMo(d1, d2):
        return (d2.year * 12 + d2.month) - (d1.year * 12 + d1.month)
    

    结果是从d1 日期到d2 日期所经过的月数。

    就这么简单。

    如果您想将其拆分为固定长度的较小单位(例如,周),则会有所不同:

    def discretizeMo(d1, d2):
        return (d2 - d1).days // 7
    

    差异来自以天为单位的月份的可变持续时间:28-29-30-31。

    【讨论】:

    • 如果我想将时间离散化为几周怎么办?那么一年有 52 周......但我认为它会变得有点复杂......
    • @Dnaiel 添加了几周的答案。在这种情况下,数学会有所不同。因为月份有不同的天数,所以“年月数学”和“日数学”是不同的。
    • 这行得通,但它以一种非常微妙的方式依赖于 Python 中的时间增量被标准化为天、秒、微秒的唯一表示这一事实。
    • @wim 嗯,是的。这是 Python,事情很简单。在没有这种规范化的其他语言中,它将是 30/31 天的月份、2 月、非闰年、mod 4 的闰年、mod 100 的非闰年、mod 400 的闰年......在这种情况下,将每个日期置于时间 0 以来的天数范围内,然后减去,然后将混乱计算回数月。幸运的是,没有花费时间,这会使情况变得更糟。
    【解决方案2】:

    你可以减去年份部分,乘以 12 得到月份的差值,然后减去月份部分:

    def discretizeMo(start_date, end_date):
        return (end_date.year - start_date.year) * 12 + \
               (end_date.month - start_date.month)
    

    从那里开始,只需在每个元素和最小值之间应用此函数即可:

    result = [discretizeMo(min(myList), x) for x in myList]
    

    【讨论】:

    • 如果我想在几周内离散化它怎么办?我正在尝试使用通用公式...
    【解决方案3】:

    这很容易,因为一年总会有 12 个月:

    def discretizeMo(d0, d):
        return (d.year - d0.year)*12 + d.month - d0.month
    

    如果您要处理多个时区,您可能需要确保 d0d 具有相同的时区,否则您可能会得到错误的结果。

    【讨论】:

    • 我正在尝试提出一个通用公式,如果我想在几周内将它们离散化怎么办?
    • 结果取决于您认为一周的开始日期。所以你必须首先做出决定。
    • 好点。没错,让我们说这一天是我们用作 d0 的开始日期的那一天。即,对于我们的示例,它将是 datetime.date(2015,02,08),即第 0 天,第 0 周。
    猜你喜欢
    • 1970-01-01
    • 2021-07-04
    • 1970-01-01
    • 2012-10-22
    • 1970-01-01
    • 2018-03-07
    • 2014-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多