【问题标题】:How trunc datetime column with pandas?如何用熊猫截断日期时间列?
【发布时间】:2014-08-29 01:44:54
【问题描述】:

我有一列包含该格式的日期:

0      2013-12-12 10:51:51
1      2013-12-12 11:11:01
2      2013-12-12 11:19:22
3      2013-12-12 11:36:48
4      2013-12-12 11:36:48

我想把它截断为

0      10:51:51
1      11:11:01
2      11:19:22
3      11:36:48
4      11:36:48

我尝试了df[":11],但它截断了列,而不是列内

【问题讨论】:

  • 这是字符串还是日期时间列?如果是字符串,则 df['date'] = df['date'].apply(lambda x: x[11:]) 否则 df['date'] = df['date'].apply(lambda x: x.time()) 应该可以工作

标签: python date pandas


【解决方案1】:

执行以下操作:

In [145]:
# do this if the dtype is a string
df['time'] = df['time'].apply(lambda x: x[11:])
df
Out[145]:
   index      time
0      0  10:51:51
1      1  11:11:01
2      2  11:19:22
3      3  11:36:48
4      4  11:36:48
In [148]:
# do this if it's a datetime
df['time'] = df['time'].apply(lambda x: x.time())
df
Out[148]:
   index      time
0      0  10:51:51
1      1  11:11:01
2      2  11:19:22
3      3  11:36:48
4      4  11:36:48

【讨论】:

  • 效果很好!我只需要复制数据框然后将其返回以避免错误。
  • 好吧,我再次需要帮助,我不得不将时间列设置为 index,但它不再起作用了。我试过d.index = d.apply(lambda x: x.time()),但我收到了这个错误AttributeError: ("'Series' object has no attribute 'time"
  • 你可以只做d.index = d.index.apply(lambda x: x.time()),或者在你把它设置为索引之前这样做
  • d.index = d.index.apply(lambda x: x.time()) 不起作用。我终于设法通过重置索引、应用并再次设置来做到这一点:df.reset_index("time", inplace=True) df['time'] = df['time'].apply(lambda x: x.time()) df.set_index("time", inplace=True)
【解决方案2】:

您可以简单地使用slice,如果该列不是str,您还需要映射到str

>>> df.tic
0   2013-12-12 10:51:51
1   2013-12-12 11:11:01
2   2013-12-12 11:19:22
3   2013-12-12 11:36:48
4   2013-12-12 11:36:48
Name: tic, dtype: datetime64[ns]
>>> df.tic.map(str).str.slice(11)
0    10:51:51
1    11:11:01
2    11:19:22
3    11:36:48
4    11:36:48
Name: tic, dtype: object

如果列是Timestamp,您也可以映射到pd.Timestamp.time

>>> df.tic.map(pd.Timestamp.time)
0    10:51:51
1    11:11:01
2    11:19:22
3    11:36:48
4    11:36:48
Name: tic, dtype: object

【讨论】:

    【解决方案3】:

    虽然有多种方法可以通过字符串格式化和转换来实现这一点,但将数据保存在 numpy 数组中可以获得最佳性能。比较以下:

    生成一些数据:

    datetimes = pd.Series(pd.date_range(start='2018-01-01', end='2018-02-01', freq='s'))
    

    转换为datetime对象数组:

    %%timeit
    datetimes.dt.time
    
    7.41 s ± 747 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    

    保存在 numpy 数组中

    %%timeit
    
    datetimes-datetimes.dt.floor(freq='D')
    
    166 ms ± 50.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    

    为了完整起见,数据比较:

    df = pd.concat([
        datetimes.rename('input'), 
        (datetimes-datetimes.dt.floor(freq='D')).rename('using floor'), 
        datetimes.dt.time.rename('using time')
    ], axis=1).head()
    

    结果数据:

    df.head(5)
    
        input               using floor     using time
    0   2018-01-01 00:00:00     00:00:00    00:00:00
    1   2018-01-01 00:00:01     00:00:01    00:00:01
    2   2018-01-01 00:00:02     00:00:02    00:00:02
    3   2018-01-01 00:00:03     00:00:03    00:00:03
    4   2018-01-01 00:00:04     00:00:04    00:00:04
    

    结果类型:

    df.dtypes
    
    input           datetime64[ns]
    using floor    timedelta64[ns]
    using time              object
    dtype: object
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-11
      • 2019-02-17
      • 2014-01-01
      • 2016-07-05
      • 2019-07-19
      • 2022-10-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多