【问题标题】:Splitting an array of dates into multiple lists as per month按月将日期数组拆分为多个列表
【发布时间】:2021-02-10 12:13:44
【问题描述】:

我有以下数组(也可以是列表):

uniqueDates = np.array([datetime.date(2017, 4, 11), datetime.date(2017, 4, 12),
                        datetime.date(2017, 4, 20), datetime.date(2017, 4, 25),
                        datetime.date(2017, 5, 3), datetime.date(2017, 5, 4),
                        datetime.date(2017, 5, 10), datetime.date(2017, 5, 11),
                        datetime.date(2017, 6, 1), datetime.date(2017, 6, 13),
                        datetime.date(2017, 6, 15), datetime.date(2017, 7, 10),
                        datetime.date(2017, 7, 13), datetime.date(2017, 7, 17)])

我想将此数组拆分为 4 个列表,每个列表都包含不同月份(4 月、5 月、6 月和 7 月)中的日期。因此,预期的结果如下所示:

monthsList = [[datetime.date(2017, 4, 11),
               datetime.date(2017, 4, 12),
               datetime.date(2017, 4, 20),
               datetime.date(2017, 4, 25)],
              [datetime.date(2017, 5, 3),
               datetime.date(2017, 5, 4),
               datetime.date(2017, 5, 10),
               datetime.date(2017, 5, 11)],
              [datetime.date(2017, 6, 1),
               datetime.date(2017, 6, 13),
               datetime.date(2017, 6, 15)],
              [datetime.date(2017, 7, 10),
               datetime.date(2017, 7, 13),
               datetime.date(2017, 7, 17)]]

我想知道是否有可以自动执行此操作的功能?或者我应该遍历元素并单独检查它们? 我正在寻找一种有效的方法来完成这项任务。我在 stackoverflow 中搜索了一些问题,但找不到我要找的东西。

【问题讨论】:

  • 如果它们的大小不同,那么您肯定需要遍历它们。
  • @NidalBarada 不。每个月可能有不同的天数,我可能有不同的月份。在某些情况下,我可能会有,例如,二月、五月、六月、八月。

标签: python arrays list date


【解决方案1】:

只要将月份组合在一起(计算量较少),这将起作用:

Dates=[]

for i in range(len(uniqueDates)):
    if(Dates==[]):
        Dates.append([uniqueDates[i]])
    elif(uniqueDates[i].month==Dates[-1][0].month):
        Dates[-1].append(uniqueDates[i])
    else:
        Dates.append([uniqueDates[i]])

否则使用:

Dates=[]

for i in range(len(uniqueDates)):
    if(Dates==[]):
        Dates.append([uniqueDates[i]])
    else:
        for y in range(len(Dates)):
            if(Dates[y][0].month == uniqueDates[i].month):
                Dates[y].append(uniqueDates[i])
                break
            if(y==len(Dates)-1):
                Dates.append([uniqueDates[i]])

两个输出:

[
    [datetime.date(2017, 4, 11), datetime.date(2017, 4, 12), datetime.date(2017, 4, 20), datetime.date(2017, 4, 25)],
    [datetime.date(2017, 5, 3), datetime.date(2017, 5, 4), datetime.date(2017, 5, 10), datetime.date(2017, 5, 11)],
    [datetime.date(2017, 6, 1), datetime.date(2017, 6, 13), datetime.date(2017, 6, 15)],
    [datetime.date(2017, 7, 10), datetime.date(2017, 7, 13), datetime.date(2017, 7, 17)]
]

将第一个与第二个函数的结果与@Tom83B 提供的熊猫答案一起计时:

Repeated: 100,000x
    First Function:   0.10295674900044105  seconds
    Second Function:  1.5613631390006049   seconds
    Pandas Function:  146.28389169599905   seconds

【讨论】:

    【解决方案2】:

    你可以使用熊猫:

    import pandas as pd
    
    ...
    
    s = pd.Series(uniqueDates)
    list(s.groupby(s.map(lambda x: x.month)))
    

    编辑:正如 Nidal Barada 所指出的,他的循环方法明显更快。在 Jupyter 中使用 %%timeit 魔法:

    pandas:每个循环 562 µs ± 3.87 µs(7 次运行的平均值 ± 标准偏差,每次 1000 个循环)

    Nidal Barada 的回答:每个循环 8.14 µs ± 39.9 ns(平均值 ± 标准偏差,7 次运行,每次 100000 次循环)

    【讨论】:

      【解决方案3】:

      您可以使用 itertools 中的 groupby:

      from itertools import groupby
      
      grouped = [[*g] for _,g in groupby(uniqueDates,key=lambda d:(d.year,d.month))]
      
      print(*(", ".join(map(str,g)) for g in grouped),sep="\n")
      
      2017-04-11, 2017-04-12, 2017-04-20, 2017-04-25
      2017-05-03, 2017-05-04, 2017-05-10, 2017-05-11
      2017-06-01, 2017-06-13, 2017-06-15
      2017-07-10, 2017-07-13, 2017-07-17
      

      即使您的输入只是一个普通的 Python 列表,这也可以工作。除非必要,否则不应使用 numpy

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-08
        • 1970-01-01
        • 1970-01-01
        • 2016-02-20
        • 1970-01-01
        相关资源
        最近更新 更多