根据列值的属性值过滤DataFrame的行

时间:2015-11-12 13:23:41

标签: python pandas

我的pandas.DataFrame包含一个包含时间戳值的列。

我特别想处理那些位于特定时间范围内的行,从开始时间到结束时间,忽略日期部分。

我尝试使用布尔数组作为索引来实现它:

import datetime
import pandas
from random import randrange as rr

# generate random timestamps
timestamps = [datetime.datetime(2000,1,1,rr(24),rr(60)) for i in xrange(100)]
# insert into DataFrame
df = pandas.DataFrame(timestamps, columns=["t"])
# try to filter based on time range
morning = df[8 <= df.t.hour < 12]

不幸的是,这不起作用:

Traceback (most recent call last):
  File "test.py", line 9, in <module>
    morning = df[8 <= df.t.hour < 12]
  File "/usr/lib/python2.7/dist-packages/pandas/core/generic.py", line 1815, in __getattr__
    (type(self).__name__, name))
AttributeError: 'Series' object has no attribute 'hour'

我试图解决这个问题:

morning = df[8 <= df.t.apply(lambda x:x.hour) < 12]

但这也失败了:

Traceback (most recent call last):
  File "test.py", line 16, in <module>
    morning = df[8 <= df.t.apply(lambda x:x.hour) < 12]
  File "/usr/lib/python2.7/dist-packages/pandas/core/generic.py", line 676, in __nonzero__
    .format(self.__class__.__name__))
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

有人能建议一种方法如何根据列值的属性值过滤DataFrame的行吗?

1 个答案:

答案 0 :(得分:2)

您需要以下内容:

df[(df['t'].dt.hour >= 8) & (df['t'].dt.hour < 12)]

首先,当dtype为datetime64时,您可以使用dt个访问者返回hour组件,您可以使用它来执行比较。

当您正在寻找范围时,您需要使用and运算符使用2个条件&,因为我们正在处理数组并将条件包装在括号中运算符优先级

In [236]:
morning = df[(df['t'].dt.hour >= 8) & (df['t'].dt.hour < 12)]
morning

Out[236]:
                     t
8  2000-01-01 09:09:00
18 2000-01-01 10:30:00
20 2000-01-01 11:58:00
21 2000-01-01 10:11:00
22 2000-01-01 10:39:00
32 2000-01-01 08:51:00
35 2000-01-01 10:32:00
42 2000-01-01 10:57:00
46 2000-01-01 11:45:00
55 2000-01-01 08:58:00
56 2000-01-01 10:26:00
60 2000-01-01 10:33:00
66 2000-01-01 11:13:00
70 2000-01-01 10:29:00
79 2000-01-01 08:23:00
80 2000-01-01 08:08:00
83 2000-01-01 10:44:00
86 2000-01-01 11:02:00
93 2000-01-01 11:14:00
97 2000-01-01 08:55:00
98 2000-01-01 10:47:00