Pandas从时间戳中提取日期
我正在使用一个 pandas 数据框,其中有一列叫做 'date_time',里面的值看起来像日期时间戳,比如:2014-02-21 17:16:42。
我可以通过 df['date_time'] 来调用这一列,我想要查找某个特定日期的行。我尝试过一些方法,像是
df[(df['date_time']=='2014-02-21')]
但是我不知道怎么从这个日期时间值中只提取出日期。另外,我不确定这是否重要,但当我检查 type(df.date_time[0]) 的时候,它返回的是字符串,而不是某种日期时间类型的对象。
非常感谢。
2 个回答
0
因为这是一个字符串,你可以试试下面这样的做法:
df[df['date_time'].str.startswith('2014-02-21')]
3
在这里不使用字符串会更有效率(假设这些数据已经是datetime64格式——你应该这样做!),因为在比较之前需要对字符串进行计算……而处理字符串的速度比较慢。
In [11]: s = pd.Series(pd.to_datetime(['2014-02-21 17:16:42', '2014-02-22 17:16:42']))
In [12]: s
Out[12]:
0 2014-02-21 17:16:42
1 2014-02-22 17:16:42
dtype: datetime64[ns]
你可以简单地进行一个排序检查:
In [13]: (pd.Timestamp('2014-02-21') < s) & (s < pd.Timestamp('2014-02-22'))
Out[13]:
0 True
1 False
dtype: bool
In [14]: s.loc[(pd.Timestamp('2014-02-21') < s) & (s < pd.Timestamp('2014-02-22'))]
Out[14]:
0 2014-02-21 17:16:42
dtype: datetime64[ns]
不过,使用DatetimeIndex.normalize
会更快(这个方法会把每个时间戳的时间部分归零,变成午夜的时间戳):
In [15]: pd.DatetimeIndex(s).normalize()
Out[15]:
<class 'pandas.tseries.index.DatetimeIndex'>
[2014-02-21, 2014-02-22]
Length: 2, Freq: None, Timezone: None
In [16]: pd.DatetimeIndex(s).normalize() == pd.Timestamp('2014-02-21')
Out[16]: array([ True, False], dtype=bool)
In [17]: s.loc[pd.DatetimeIndex(s).normalize() == pd.Timestamp('2014-02-21')]
Out[17]:
0 2014-02-21 17:16:42
dtype: datetime64[ns]
这里有一些时间测试(s的单位如上所述):
In [21]: %timeit s.loc[s.str.startswith('2014-02-21')]
1000 loops, best of 3: 1.16 ms per loop
In [22]: %timeit s.loc[(pd.Timestamp('2014-02-21') < s) & (s < pd.Timestamp('2014-02-22'))]
1000 loops, best of 3: 1.23 ms per loop
In [23]: %timeit s.loc[pd.DatetimeIndex(s).normalize() == pd.Timestamp('2014-02-21')]
1000 loops, best of 3: 405 µs per loop
当s稍微大一点时,结果会更明显:
In [31]: s = pd.Series(pd.to_datetime(['2014-02-21 17:16:42', '2014-02-22 17:16:42'] * 1000))
In [32]: %timeit s.loc[s.str.startswith('2014-02-21')]
10 loops, best of 3: 105 ms per loop
In [33]: %timeit s.loc[(pd.Timestamp('2014-02-21') < s) & (s < pd.Timestamp('2014-02-22'))]
1000 loops, best of 3: 1.3 ms per loop
In [34]: %timeit s.loc[pd.DatetimeIndex(s).normalize() == pd.Timestamp('2014-02-21')]
1000 loops, best of 3: 694 µs per loop
注意:在你的例子中,列df['date_time']
就是s,你会执行df.loc[pd.DatetimeIndex(df['date_time']) == ...]
。