Python错误:TypeError:(“<class'pandas._libs.tslibs.Timedelta.Timedelta'>不可转换为datetime”)

2024-06-16 09:43:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在计算两次之间的差值,单位为分钟。我有一个数据框,它有四列:

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)

当我在dataframe中创建一个新列时,上面的函数可以正常工作。比如说,

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

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

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

当我运行上述代码时,它会抛出一条错误消息:

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

它指向第一个函数的第五行(即timediff =pd.to_datetime(timediff))。我试图解决这个问题,但失败了。有人能告诉我哪里出了错吗


Tags: to函数dfdatetimedateobjecttimecalc
1条回答
网友
1楼 · 发布于 2024-06-16 09:43:05

我尝试在Python3.8和pandas 1.1.0上复制您的代码。我从第一个函数中得到了错误TypeError: dtype timedelta64[ns] cannot be converted to datetime64[ns]。我认为这个错误是不言自明的:您不能通过对时间差调用_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]。然后可以直接开始计算时间增量,例如:

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(),而不是构建自己的。内置函数对于格式问题非常健壮

我知道所有这些都可能有点混乱,需要时间来澄清。但帮助我的是与熊猫提供的工具的使用保持一致

我真诚地希望上述帮助

相关问题 更多 >