【问题标题】:Why is the difference of datetime = zero for two rows in a dataframe?为什么数据框中两行的 datetime = 0 的差异?
【发布时间】:2019-11-17 12:58:45
【问题描述】:

我面临的这个问题很简单,也很奇怪,一直困扰着我。

我有一个如下的数据框:

df['datetime'] = df['datetime'].dt.tz_convert('US/Pacific') 
#converting datetime from datetime64[ns, UTC] to datetime64[ns,US/Pacific]

df.head()

                vehicle_id  trip_id                                 datetime    
        6760612 1000500 4f874888ce404720a203e36f1cf5b716    2017-01-01 10:00:00-08:00       
        6760613 1000500 4f874888ce404720a203e36f1cf5b716    2017-01-01 10:00:01-08:00    
        6760614 1000500 4f874888ce404720a203e36f1cf5b716    2017-01-01 10:00:02-08:00      
        6760615 1000500 4f874888ce404720a203e36f1cf5b716    2017-01-01 10:00:03-08:00       
        6760616 1000500 4f874888ce404720a203e36f1cf5b716    2017-01-01 10:00:04-08:00

df.info ()

vehicle_id         int64
trip_id            object
datetime           datetime64[ns, US/Pacific]

我试图找出数据时间差异如下(以两种不同的方式):

df['datetime_diff'] = df['datetime'].diff()

df['time_diff'] = (df['datetime'] - df['datetime'].shift(1)).astype('timedelta64[s]')

对于特定的trip_id,我的结果如下:

df[trip_frame['trip_id'] == '4f874888ce404720a203e36f1cf5b716'][['datetime','datetime_diff','time_diff']].head()

        datetime                  datetime_diff time_diff
6760612 2017-01-01 10:00:00-08:00   NaT             NaN
6760613 2017-01-01 10:00:01-08:00   00:00:01        1.0
6760614 2017-01-01 10:00:02-08:00   00:00:01        1.0
6760615 2017-01-01 10:00:03-08:00   00:00:01        1.0
6760616 2017-01-01 10:00:04-08:00   00:00:01        1.0

但是对于像下面这样的其他一些trip_id,您可以观察到我的日期时间差为零(对于两列),而实际上不是。时间差以秒为单位。

df[trip_frame['trip_id'] == '01b8a24510cd4e4684d67b96369286e0'][['datetime','datetime_diff','time_diff']].head(4)

         datetime            datetime_diff  time_diff
3236107 2017-01-28 03:00:00-08:00   0 days  0.0
3236108 2017-01-28 03:00:01-08:00   0 days  0.0
3236109 2017-01-28 03:00:02-08:00   0 days  0.0
3236110 2017-01-28 03:00:03-08:00   0 days  0.0

df[df['trip_id'] == '01c2a70c25e5428bb33811ca5eb19270'][['datetime','datetime_diff','time_diff']].head(4)

        datetime             datetime_diff  time_diff
8915474 2017-01-21 10:00:00-08:00   0 days  0.0
8915475 2017-01-21 10:00:01-08:00   0 days  0.0
8915476 2017-01-21 10:00:02-08:00   0 days  0.0
8915477 2017-01-21 10:00:03-08:00   0 days  0.0

关于实际问题的任何线索?我将不胜感激。

【问题讨论】:

  • 你能发布你的部分数据来测试代码吗?
  • 数据相当庞大。以上数据和信息没有帮助吗?
  • 只有一部分数据可以工作,这样我就可以重现您的错误。

标签: python pandas numpy dataframe datetime


【解决方案1】:

如果我只执行你的代码而不进行类型转换,一切看起来都很好:

df.timestamp - df.timestamp.shift(1)

关于示例行

rows=['2017-01-21 10:00:00-08:00',
 '2017-01-21 10:00:01-08:00',
 '2017-01-21 10:00:02-08:00',
 '2017-01-21 10:00:03-08:00',
 '2017-01-21 10:00:03-08:00']  # the above lines are from your example. I just invented this last line to have one equal entry
df= pd.DataFrame(rows, columns=['timestamp'])
df['timestamp']= df['timestamp'].astype('datetime64')
df.timestamp - df.timestamp.shift(1)

最后一行返回

Out[40]: 
0        NaT
1   00:00:01
2   00:00:01
3   00:00:01
4   00:00:00
Name: timestamp, dtype: timedelta64[ns]

到目前为止,这看起来并不可疑。请注意,您已经有一个 timedelta64 系列。

如果我现在添加您的转化,我会得到:

(df.timestamp - df.timestamp.shift(1)).astype('timedelta64[s]')
Out[42]: 
0    NaN
1    1.0
2    1.0
3    1.0
4    0.0
Name: timestamp, dtype: float64

你看,结果是一系列浮点数。这可能是因为该系列中有一个NaN。另一件事是添加[s]。这似乎不起作用。如果您使用[ns],它似乎可以工作。如果你想以某种方式摆脱纳秒,我想你需要单独做。

【讨论】:

  • 如果我使用df['timestamp']= df['timestamp'].astype('datetime64') ,我得到以下-TypeError: cannot astype a timedelta from [timedelta64[ns]] to [datetime64],也就是说,日期时间已经是timedelta64类型了。我的主要问题是 datetime 差异 不应该为零。 日期时间差的格式无关紧要。
  • 日期时间差异的类型如何无关紧要,或者您只是指输出格式。请不要将.astype('datetime64') 应用于您的数据。我只是用它以我认为您的数据看起来像的方式准备我的测试数据(例如:从字符串转换为时间戳)。你不需要这一步。从我观察到的df.timestamp - df.timestamp.shift(1) 应该已经给了你,你想要的。如果不是这样,如果没有一些测试数据和your_df.dtypes 的输出,我将无法为您提供任何帮助。感谢您的耐心等待。
  • 是的,我指的是输出格式。已使用功能的数据类型更新了问题。我应该感谢您为解决我的问题所做的努力。
  • 感谢您提供的数据,清楚地表明了您的意思。您确定在您的01b8a24510cd4e4684d67b96369286e0 记录之间没有其他记录,这可能会破坏您的结果吗?我的意思是,数据集是按索引顺序排序的,还是您以其他方式排序并且只是在相同的trip_id 中保留了索引?如果按索引排序,我认为您观察到的是一个错误,应该报告。
  • 如果您不确定,您可以尝试通过 reset_index 验证您的问题在重新索引的数据帧上仍然存在,然后在新插入的包含冲突的列上选择冲突记录旧索引。如果这只从您的帖子中选择 delta=0 的记录,它不应该是 0 并且没有不属于同一个 trip_id 的记录,我认为您应该打开一个错误票。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 2022-12-09
  • 2018-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多