计算python日期时间的平均值

Posted

技术标签:

【中文标题】计算python日期时间的平均值【英文标题】:computing the mean for python datetime 【发布时间】:2018-10-25 18:44:44 【问题描述】:

我有一个日期时间属性:

d = 
    'DOB': pd.Series([
        datetime.datetime(2014, 7, 9),
        datetime.datetime(2014, 7, 15),
        np.datetime64('NaT')
    ], index=['a', 'b', 'c'])

df_test = pd.DataFrame(d)

我想计算该属性的平均值。运行 mean() 会导致错误:

TypeError: 此 dtype 不允许归约操作 'mean'

我还尝试了elsewhere 提出的解决方案。它不起作用,因为运行那里提出的功能会导致

OverflowError: Python int 太大而无法转换为 C long

你有什么建议?上述数据框的结果应该等同于

datetime.datetime(2014, 7, 12).

【问题讨论】:

您可以使用.totimestamp()datetime 值转换为连续浮点值,计算其平均值并通过datetime.fromtimestamp() 转换结果。请记住,由于 lapse-seconds、-days、-whatever,您可能会得到奇怪的日历效果。 @user2722968 你会写一个可行的解决方案吗?我很乐意接受它——如果它有效的话。 【参考方案1】:

日期时间数学支持一些标准运算:

a = datetime.datetime(2014, 7, 9)
b = datetime.datetime(2014, 7, 15)
c = (b - a)/2

# here c will be datetime.timedelta(3)

a + c
Out[7]: datetime.datetime(2014, 7, 12, 0, 0)

因此,您可以编写一个函数,给定两个日期时间,减去较大的较小的形式,并将差的一半添加到较小的。将此功能应用于您的数据框,然后 shazam!

【讨论】:

【参考方案2】:

如果您愿意,您可以使用unix time。这被定义为自1970-01-01 以来的总秒数(例如)。这样一来,您的所有时间都只是浮点数,因此很容易在列上进行简单的数学运算。

import pandas as pd

df_test['unix_time'] = (df_test.DOB - pd.to_datetime('1970-01-01')).dt.total_seconds()

df_test['unix_time'].mean()
#1405123200.0

# You want it in date, so just convert back
pd.to_datetime(df_test['unix_time'].mean(), origin='unix', unit='s')
#Timestamp('2014-07-12 00:00:00')

【讨论】:

问题是我想要一个通用的解决方案。我的日期早于 1970-01-01 - 我只是没有在上面显示。 @Nick 我没有看到这个问题。肯定有负数,所以你可以有负的unix时间。 例如将datetime.datetime(1800, 7, 9) 添加到您的df 没有任何问题发生。【参考方案3】:

您可以取Timedelta 的平均值。所以找到最小值并从系列中减去它以获得一系列Timedelta。然后取平均值并将其加回最小值。

dob = df_test.DOB
m = dob.min()
(m + (dob - m).mean()).to_pydatetime()

datetime.datetime(2014, 7, 12, 0, 0)

单行

df_test.DOB.pipe(lambda d: (lambda m: m + (d - m).mean())(d.min())).to_pydatetime()

致@ALollz point

我使用纪元 pd.Timestamp(0) 而不是 min

df_test.DOB.pipe(lambda d: (lambda m: m + (d - m).mean())(pd.Timestamp(0))).to_pydatetime()

【讨论】:

谢谢!为了完整起见,您是否可以添加从时间戳到日期时间的转换? 它甚至需要是最小值,还是你可以减去一些任意日期,然后再把它加回来? @ALollz 你是对的。但最低限度是一个简单的保证。假设我减去了时代......它似乎与你的答案非常相似。 是的,我刚刚意识到同样的事情!我同意最低限度是一个很好的保证。 +1【参考方案4】:

您可以使用带有 np.int64 的 astype 转换纪元时间,并使用 pd.to_datetime 转换回日期时间:

pd.to_datetime(df_test.DOB.dropna().astype(np.int64).mean())

输出:

Timestamp('2014-07-12 00:00:00')

【讨论】:

【参考方案5】:

从 pandas=0.25 开始,可以计算日期时间序列的平均值。

In [1]: import pandas as pd
   ...: import numpy as np

In [2]: s = pd.Series([
   ...:     pd.datetime(2014, 7, 9),
   ...:     pd.datetime(2014, 7, 15),
   ...:     np.datetime64('NaT')])

In [3]: s.mean()
Out[3]: Timestamp('2014-07-12 00:00:00')

但是,请注意,将均值应用于 pandas 数据框目前会忽略具有日期时间序列的列。

【讨论】:

以上是关于计算python日期时间的平均值的主要内容,如果未能解决你的问题,请参考以下文章

计算日期/时间部分的平均值

如何计算日期时间范围内的 n 个平均值?

如何按日期顺序计算日期之间的平均天数

Excel中有日期(一年365天)、时间(一天24小时)、风速、风向、温度、辐照等数据,现在我要计算

根据日期范围计算滚动平均值[重复]

根据日期范围计算运行平均值