首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >django/python中的逐月数据计算

django/python中的逐月数据计算
EN

Stack Overflow用户
提问于 2021-10-07 08:50:25
回答 3查看 196关注 0票数 2

我得到的输入是start_date和end_date,现在我想根据start_date和end_date之间的几个月来获取数据。如何在python/django中做到这一点?

-格式的约会

代码语言:javascript
复制
start_date = '2021-5-5'   #YYYY-MM-DD format
end_date = '2021-6-5'   

必需的结果-

代码语言:javascript
复制
result = [
    {
        'month' : 'may',  
        'data' : data_for_may  # from date 5th of may to 31st of may
    },
    {
        'month' : 'june',
        'data' : data_for_june  # from date 1st of june to 5th of june
    }
]
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-10-07 10:16:14

我觉得你最好这样做:

代码语言:javascript
复制
from datetime import datetime
from django.db.models import Count
from django.contrib.auth.models import User

start_date = datetime.strptime('2021-5-5' , '%Y-%m-%d')
month_end_date = datetime.strptime('2021-6-5' , '%Y-%m-%d')

# SELECT year(last_login), month(last_login), count(*) 
# FROM auth_user 
# GROUP BY year(last_login), month(last_login)
# ORDER BY year(last_login), month(last_login)
qs = (User.objects.values('last_login__month', 'last_login__year')
                  .annotate(data=Count('*'))
                  .order_by('last_login__year', 'last_login__month'))
# WHERE last_login ...
qs = qs.filter(last_login__range=[start_date, month_end_date])

result = []
for item in qs:
    result.append({
        # get pretty name i.e "January"
        'month': datetime(1900, item['last_login__month'] , 1).strftime('%B'),
        'data': item['data']
    })

result  # [{'month': 'May', 'data': 81}, {'month': 'June', 'data': 15}])

为什么我觉得这样更好?(对所提供的其他答复)

你将只有一个记录,每个月,易于量化/预测,更好的性能。

顺便说一句,我给你写了测试;)

https://gist.github.com/kingbuzzman/0197da03c52ae9a798c99d0cf58c758c#file-month_data-py-L82-L133

作为gist内部的注释,我提供了如何使用docker测试它的示例。

票数 1
EN

Stack Overflow用户

发布于 2021-10-07 09:25:56

根据您拥有的数据数量,我将在一个查询中获取所有数据,按日期时间排序,然后在Python中对它们进行分组。下面的片段说明了这个想法。

代码语言:javascript
复制
from itertools import groupby

data = User.objects.order_by('last_login')

result = []
for (year, month), data_per_month in groupby(data, key=lambda x: (x.last_login.year(), x.last_login.month())):
    result.append({
        'year': year,
        'month': month,
        'data': data_per_month   
    })

这可能是快速和容易地与10,000多个对象的内存相匹配。然而,当获取数百万条记录时,您可能需要重新考虑。

票数 1
EN

Stack Overflow用户

发布于 2021-10-07 09:17:24

首先,您需要将字符串转换为日期:

代码语言:javascript
复制
start_date = datetime.strptime(start_date , '%Y-%m-%d')
end_date = datetime.strptime(end_date , '%Y-%m-%d')

然后,您可以在每个月迭代以填充您的results数组:

代码语言:javascript
复制
start_date = datetime.datetime.strptime(start_date, '%Y-%m-%d')
end_date = datetime.datetime.strptime(end_date, '%Y-%m-%d')

all_data = User.objects.filter(last_login__date__range=[start_date, end_date])
results = []
while start_date.year < end_date.year or start_date.month <= end_date.month:
    results.append({
        'month': start_date.strftime('%B'),
        'year': start_date.strftime('%Y'),
        'data': all_data.filter(last_login__date__month=start_date.month, last_login__date__year=start_date.year)
    })
    # Increment the start_date by one month using the dateutil library
    start_date = start_date + dateutil.relativedelta(months=+1)

注意:我为这个解决方案编辑了我的第一个想法,并在Django项目中进行了测试。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69478156

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档