Python - 按月分组日期

时间:2018-03-31 06:27:18

标签: python datetime itertools

这是一个快速的问题,我起初认为这很容易。一个小时,我不太确定! 所以,我有一个Python datetime对象列表,我想绘制它们。 x值是年和月,y值是此列表中本月发生的日期对象的数量。
也许一个例子会更好地证明这一点(dd / mm / yyyy):

[28/02/2018, 01/03/2018, 16/03/2018, 17/05/2018] 
-> ([02/2018, 03/2018, 04/2018, 05/2018], [1, 2, 0, 1])

我的第一次尝试尝试按日期和年份分组:

import itertools
group = itertools.groupby(dates, lambda date: date.strftime("%b/%Y"))
graph = zip(*[(k, len(list(v)) for k, v in group]) # format the data for graphing

尽管您可能已经注意到,但这只会按照列表中已有的日期进行分组。在我上面的例子中,4月份没有发生日期的事实会被忽视。

接下来,我尝试查找开始日期和结束日期,并在它们之间循环几个月:

import datetime
data = [[], [],]
for year in range(min_date.year, max_date.year):
    for month in range(min_date.month, max_date.month):
        k = datetime.datetime(year=year, month=month, day=1).strftime("%b/%Y")
        v = sum([1 for date in dates if date.strftime("%b/%Y") == k])
        data[0].append(k)
        data[1].append(v)

当然,这仅在min_date.month小于max_date.month时有效,如果它们跨越多年,则不一定如此。而且,它非常难看。

有这种优雅的方式吗?
提前致谢

编辑:要明确的是,日期是datetime个对象,而不是字符串。为了便于阅读,它们在这里看起来像字符串。

2 个答案:

答案 0 :(得分:5)

我建议使用pandas

date

graph

<强>解释

  1. 首先从PeriodIndex列表中创建Series并转换to_datetime s。
  2. Series.dt.to_period
  3. 创建level=0
  4. groupby按索引(static Mat blackcolorfilter(cv::Mat img, int threshold) { cv::Mat temp; cv::cvtColor(img, temp, CV_RGB2HSV); cv::Scalar lowerColor(0, 0, 0), higherColor(255, 255, threshold); cv::inRange( temp, lowerColor, higherColor, img); return img; } )并按GroupBy.size
  5. 获取计数
  6. Series.reindex按照{/ 3>}的最大值和最小值创建的缺失期间
  7. 最后的情节,例如对于酒吧 - PeriodIndex

答案 1 :(得分:0)

使用计数器

dates = list()
import random
import collections

for y in range(2015,2019):
  for m in range(1,13):
    for i in range(random.randint(1,4)):
      dates.append("{}/{}".format(m,y))

print(dates)
counter = collections.Counter(dates)
print(counter)

对于没有出现日期的问题,您可以使用Counter的subtract方法 生成一个包含所有日期范围的列表,每个日期只会出现在列表中一次,然后您可以使用减法 像这样

tmp_date_list = ["{}/{}".format(m,y) for y in range(2015,2019) for m in range(1,13)]
counter.subtract(tmp_date_list)