【问题标题】:Python error: TypeError: ("<class 'pandas._libs.tslibs.timedeltas.Timedelta'> is not convertible to datetime")Python 错误:TypeError:(“<class 'pandas._libs.tslibs.timedeltas.Timedelta'> 不能转换为日期时间”)
【发布时间】:2020-03-15 23:58:22
【问题描述】:

我以分钟为单位计算两次之间的差异。我有一个有四列的数据框:

df1:

 Notified Start Time', 'Notified End Time',  'Actual Int Start Time', 'Actual Int End Time'
0      3/01/2020 9:00   3/01/2020 19:00          3/01/2020 9:00              3/01/2020 14:00
1      4/01/2020 9:00   4/01/2020 17:00          5/01/2020 9:00              5/01/2020 20:00
2      6/01/2020 8:30   6/01/2020 20:00          7/01/2020 8:30              7/01/2020 19:00
3      8/01/2020 8:30   8/01/2020 12:00          9/01/2020 9:00              9/01/2020 18:00

数据框的数据类型为:

Notified Start Time                object
Notified End Time                  object
Actual Int Start Time              object
Actual Int End Time                object

我定义了一个函数,以分钟为单位计算两个日期之间的时间长度。

def calc_timeDiff(start_date,end_date):
    fmt = '%d/%m/%Y %H:%M'

    end_date = pd.to_datetime(end_date,format=fmt)

    start_date = pd.to_datetime(start_date,format=fmt)            
    timediff = end_date - start_date

    timediff =pd.to_datetime(timediff)
    return (timediff.dt.hour * 60 + timediff.dt.minute + (timediff.dt.second/60)).astype(float)

当我在数据框中创建一个新列时,上述函数可以正常工作。例如,

df['ActualLength'] =  calc_timeDiff(df['Actual Int Start Time'],df['Actual Int End Time'])
df['NotifiedLength'] =  calc_timeDiff(df['Notified Start Time'],df['Notified End Time'])

当我尝试在计算某个值的其他函数中使用相同的函数时,问题就出现了。

def calc_value(func_df):
   if func_df['NotifiedLength'] < func_df['ActualLength']:
      if (func_df['Actual Int Start Time'] >= func_df['Notified Start Time']):
         fullValue = func_df['ActualLength'] - calc_timeDiff(func_df['Notified End Time'],func_df['Actual Int End Time'])
         return fullValue

我调用第二个函数在数据框中创建另一列:

df['ActualOutage'] = df.apply(calc_value,axis=1) 

当我运行上面的代码时,它会抛出一个错误消息:

 TypeError: ("<class 'pandas._libs.tslibs.timedeltas.Timedelta'> is not convertible to datetime", 'occurred at index 2') 

它指向第一个函数的第 5 行(即timediff =pd.to_datetime(timediff))。我试图解决问题,但失败了。谁能指导我我在哪里犯了错误?

【问题讨论】:

  • 注释掉那一行。
  • 对不起,我没明白,你说的那条线是什么意思。
  • 您不需要转换为日期时间对象。 timediff 是/是 timedelta 对象。注释导致错误的行(将# 放在它前面)。然后看看会发生什么。 - pandas.pydata.org/docs/user_guide/timedeltas.html#attributes
  • 我已经试过,当我注释掉转换行时,它会抛出 AttributeError 错误:'TimedeltaProperties' object has no attribute 'hour'(指向第一个函数的最后一行)跨度>
  • 阅读我发布的文档链接 - total_minutes 应该是 timediff.dt.total_seconds() / 60。 - pandas.pydata.org/docs/user_guide/timedeltas.html#attributes

标签: python python-3.x python-datetime


【解决方案1】:

我尝试在 python 3.8 和 pandas 1.1.0 上重现您的代码。我从第一个函数中得到了错误TypeError: dtype timedelta64[ns] cannot be converted to datetime64[ns]。我认为该错误是不言自明的:您无法通过调用 to_datetime() 将时差转换为时间戳。 timedelta 没有时间参考以转换为戳记。话虽如此,我很惊讶您的代码没有在第一个函数中引发错误。

这是一个对我有用的可能解决方案。将数据框中的每一列转换为时间戳。

df['Notified Start Time']=pd.to_datetime(df['Notified Start Time'])
df['Notified End Time']=pd.to_datetime(df['Notified End Time'])
df['Actual Int Start Time']=pd.to_datetime(df['Actual Int Start Time'])
df['Actual Int End Time']=pd.to_datetime(df['Actual Int End Time'])

现在,如果您在数据框上运行 df.info(verbose=True),您将看到所有内容都已转换为 datetime64[ns]。然后就可以直接开始计算timedeltas了,例如:

df['ActualLength']=df['Actual Int End Time']-df['Actual Int Start Time']
df['ActualLength']
0   0 days 05:00:00
1   0 days 11:00:00
2   0 days 10:30:00
3   0 days 09:00:00
Name: ActualLength, dtype: timedelta64[ns]

df['NotifiedLength']=df['Notified End Time']-df['Notified Start Time']
df['NotifiedLength']
0   0 days 10:00:00
1   0 days 08:00:00
2   0 days 11:30:00
3   0 days 03:30:00
Name: NotifiedLength, dtype: timedelta64[ns]

或者直接在新计算的列上执行计算总经过时间的操作:

df.ActualLength.iloc[0].total_seconds()/60  
300.0

或者定义一个新列,您现在可以在其上执行子集操作作为选择规则:

df['dL']=(df.ActualLength-df.NotifiedLength).dt.total_seconds()
df['dL']
0   -18000.0
1    10800.0
2    -3600.0
3    19800.0
Name: dL, dtype: float64

最终建议:如果您的数据框中已经有 TimestampTimedelta 列,请利用内置的 Pandas 函数,例如 pd.date_range()pd.timedelta_range()pd.period_range(),而不是自己构建。内置函数对于格式问题非常强大。

我知道所有这些都可能有点令人困惑,并且需要时间来清理它。但帮助我的是与 Pandas 提供的工具的使用保持一致。

我真诚地希望以上内容有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-11
    • 1970-01-01
    • 2016-01-27
    • 2016-03-21
    • 1970-01-01
    相关资源
    最近更新 更多