Python比较时间戳和输入时间

4

我有一些带有时间戳列的数据帧,我想用np.where过滤8:00:00到17:00:00之间的行。但是我一直在接收关于数据/对象类型的错误信息。任何帮助将不胜感激。

示例:

timestamp    volume
2013-03-01 07:59:00    5
2013-03-01 08:00:00    6
2013-03-01 08:01:00    7
2013-03-01 08:02:00    8

基本上,我想结束这个。
2013-03-01 08:00:00    6
2013-03-01 08:01:00    7
2013-03-01 08:02:00    8

通过类似的方法

np.where(df['timestamp'] > dt.time('8:00:00')

1
发布你一直收到的错误信息:它们通常会告诉你你做错了什么。 - TemporalWolf
df['timestamp'].dtype 是什么? - juanpa.arrivillaga
如果第二行应该包含在结果集中,您需要使用>=。此外,无论dtype是对象还是日期时间,df[df.timestamp > '08:00:00']都应该可以工作。 - cmaher
1
df.set_index('timestamp').between_time('08:00','17:00').reset_index()? - MaxU - stand with Ukraine
df['timestamp'].dtype显示dtype('O')。我尝试了df[df.timestamp > '08:00:00'],但没有成功 - 表返回空数据框。np.where(df['timestamp'] > dt.time('8:00:00'))产生TypeError:描述符'time'需要一个'datetime.datetime'对象,但收到了一个'str'。 - yusica
是的,我检查了一下,你的时间戳中的YYYY-mm-dd部分已经在我的索引中了,这就导致了我的答案出错。正如下面的答案所建议的那样,如果你需要比较大量的日期,最好将df.timestamp转换为datetime格式。如果你可以在字符串中包含日期(即你正在查看单日的时间戳),那么你可以使用df[df.timestamp >= '2013-03-01 08:00:00'] - cmaher
3个回答

2

试试这个:

In [226]: df
Out[226]:
             timestamp  volume
0  2013-03-01 07:59:00       5
1  2013-03-01 08:00:00       6
2  2013-03-01 08:01:00       7
3  2013-03-01 08:02:00       8

In [227]: df.dtypes
Out[227]:
timestamp    object
volume        int64
dtype: object

In [228]: df['timestamp'] = pd.to_datetime(df['timestamp'], errors='coerce')

In [229]: df.dtypes
Out[229]:
timestamp    datetime64[ns]  # <---- it's `datetime64[ns]` now
volume                int64
dtype: object

In [230]: df.set_index('timestamp').between_time('08:00','17:00').reset_index()
Out[230]:
            timestamp  volume
0 2013-03-01 08:00:00       6
1 2013-03-01 08:01:00       7
2 2013-03-01 08:02:00       8

我能够运行它,直到我查看了结果数据透视表并发现早于8:00:00的时间仍然存在。我的数据包含多天,所以我想知道这是否有效?我将生成的数据打印成csv文件,仍然可以看到此时期之外的时间戳。 - yusica
我的错误,忘记设置要更新的数据框。这个方法很有效。 - yusica

2

您可以使用between函数。

我使用下面的代码生成了一个样本数据框:

import datetime
d = {'timestamp': pd.Series([datetime.datetime.now() + 
          datetime.timedelta(hours=i) for i in range(20)]),
    'volume': pd.Series([s for s in range(20)])}
df = pd.DataFrame(d)

df['timeframe'] is

0    2017-02-13 22:37:54.515840
1    2017-02-13 23:37:54.515859
2    2017-02-14 00:37:54.515865
3    2017-02-14 01:37:54.515870
4    2017-02-14 02:37:54.515878
5    2017-02-14 03:37:54.515884
6    2017-02-14 04:37:54.515888
...
17   2017-02-14 15:37:54.515939
18   2017-02-14 16:37:54.515943
19   2017-02-14 17:37:54.515948

df.dtypes

timestamp    datetime64[ns]
volume                int64
dtype: object

就像你的例子中,df['timestamp']dtypeobject,因此你可以这样做:

df['timestamp'] = pd.to_datetime(df['timestamp'], coerce=True)

通过设置参数coerce=True,如果转换某个特定字符串失败,则这些行将被设置为NaT

然后可以使用以下方式使用between进行过滤

df[df.timestamp.dt.strftime('%H:%M:%S').between('11:00:00','18:00:00')] 将返回

13 2017-02-14 11:37:54.515922      13
14 2017-02-14 12:37:54.515926      14
15 2017-02-14 13:37:54.515930      15
16 2017-02-14 14:37:54.515935      16
17 2017-02-14 15:37:54.515939      17
18 2017-02-14 16:37:54.515943      18
19 2017-02-14 17:37:54.515948      19

出现了错误,因为我的时间戳数据类型是对象,而不是datetime64 [ns]。收到错误消息:只能在日期时间值上使用.dt访问器。 - yusica
你能在过滤之前尝试 df['date time'] = pd.to_datetime(df['timestamp'], coerce=True) 吗? - saloua

0
如果你有一个包含以下数据的文件: 时间戳 交易量 2013-03-01 07:59:00 5 2013-03-01 08:00:00 6 2013-03-01 08:01:00 7 2013-03-01 08:02:00 8
那么在读取时,你可以跳过第一行,得到的输出为: 时间戳 交易量 2013-03-01 08:00:00 6 2013-03-01 08:01:00 7 2013-03-01 08:02:00 8
import pandas as pd
df=pd.read_csv("filename",skiprows=1)
print(df)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接