【问题标题】:Sum TimeField hours/minutes with Pandas用 Pandas 求和 TimeField 小时/分钟
【发布时间】:2019-03-02 04:14:37
【问题描述】:

我正在尝试使用 Pandas 对一系列时间(小时、分钟)求和。数据来自 TimeField

class PhoneRecord ( models.Model ):
    et = models.TimeField ( null=True, blank=True )

在 python 中,我获取记录并转换为数据框。

phone = PhoneRecord.objects.all()

df = read_frame ( phone )

df.et = df.et.fillna ( '00:00:00' )    # some records are blank

df [ "time" ] = pd.to_datetime(df.et, format = '%H:%M:%S', errors = 'coerce')

这给了我以下输出。

0      00:00:35
1      00:00:29
2      00:00:00
3      00:00:00
4      00:00:37
       ......

当我尝试求和时

df.time.sum ()

我收到如下错误:+ 的操作数类型不受支持:“datetime.time”和“datetime.time”

我需要做什么才能对数据进行求和和平均。

谢谢。

【问题讨论】:

  • 转换为 timedelta 并求均值:pd.to_timedelta(df.time).mean() # Timedelta('0 days 00:00:20.200000')
  • 抱歉,对此不确定:“转换为 timedelta”。谢谢。
  • 要运行的代码也在同一个注释里,看看吧。
  • 我输入了一个 print() 并针对此错误: timedelta scalar 的类型无效:
  • 抱歉,这不是我的日常工作 - 很明显。

标签: python django pandas


【解决方案1】:

您只需在此处运行自定义 1-liner 将 time 对象组合成 timedelta 对象,然后可以将它们相加在一起。 (见“打印”行)

from datetime import datetime, timedelta
import pandas as pd

phone = PhoneRecord.objects.all()
df = pd.DataFrame(list([i.__dict__ for i in phone])) # create pd.df from model query
df.et = df.et.fillna('00:00:00')  # some records are blank
print(df.et)
print("SUM:", sum([datetime.combine(datetime.min, time) - datetime.min for time in df.et.tolist()], timedelta()))

你应该得到这样的东西:

0    00:00:20
1    00:00:20
2    00:00:50
3    00:00:30
4    00:00:20

SUM: 0:02:20

我不得不稍微改变一下,让它们在我的最终工作,所以希望你和你的 Pandas 和 Django 版本是一样的。希望这会有所帮助!

【讨论】:

    【解决方案2】:

    所有计算,例如获取平均值、计数等都应(如果可能)使用数据库引擎执行。我不知道潜在的问题,但是在服务器端使用pandas 来获取平均值绝对是矫枉过正。您需要查看 Django 的aggregation facility

    另外,您可能需要重新构建模型。如果您需要存储电话交谈的持续时间,您可以使用 FloatField 代替,例如

    class PhoneRecord(models.Model):
        duration = models.FloatField(blank=True, default=0.0, help_text=_('duration in seconds')) 
        # other fields... 
        # also, you can set up  the duration field with `editable=False`, and 
        # calculate its value each time the record is created
    

    在这种情况下你可以使用Avg:

    from django.db.models import Avg
    PhoneRecords.objects.all().aggregate(Avg('duration'))
    

    得到这样的东西

    {'duration_avg': 12.3}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-15
      • 2014-01-16
      • 2019-12-21
      • 1970-01-01
      • 1970-01-01
      • 2017-03-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多