Pandas从时间戳中提取日期

3 投票
2 回答
2851 浏览
提问于 2025-04-18 08:20

我正在使用一个 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']) == ...]

撰写回答