【问题标题】:Python & Pandas: Convert series of datetime-values to consecutive day-indicesPython & Pandas:将一系列日期时间值转换为连续的日索引
【发布时间】:2014-06-10 10:11:00
【问题描述】:

我在 pandas 中有一个系列 a

>>> type(a)
<class 'pandas.core.series.Series'>

datetime64[ns] 值组成:

>>> print a
0   2000-11-01
...
10   2000-11-04
11   2000-11-05
...
Name: date, dtype: datetime64[ns]

我想将其转换为描述日期的整数系列,而第一个值 (2000-11-01) 的索引应为 1。目前我正在使用:

b = (a-a.min()).astype('timedelta64[D]').astype(int)+1

所以我首先减去最小的 datetime64 (a-a.min()),得到一个 timedelta64[ns],我首先需要将其转换为天数 (timedelta64[D]),然后再转换为整数值。从timedelta64[ns]int 的直接转换是不可能的。

我想知道是否有更好的方法来做到这一点。 对于我当前包含超过 800k 行的系列对象,这已经需要 4secs Oo


编辑

该系列包含几个月的日期时间。具有作为连续日序列的结果整数值的示例数据。在这种情况下,2000-11-03 是最旧的日期,因此如上所述获得索引 1。日期时间 2000-11-05 不存在(应该是索引 3),但仍应分配 2000-11-06 4因为这是从2000-11-03开始的第四天:

2000-01-03 -> 1
2000-01-04 -> 2
2000-01-06 -> 4
...
2000-01-31 -> 29
2000-02-01 -> 30
2000-02-02 -> 31
2000-02-04 -> 33
...

【问题讨论】:

  • 你每天都有一个条目吗?如果是这样,答案就变得微不足道:您的(整数)索引已经是您所寻求的......关于该系列的其他信息可能会提供有关可能技巧的想法
  • @FooBar:谢谢,我添加了示例数据和应该作为对话结果分配的值。我认为一天作为整数本身并不足以满足我想要做的事情。
  • 什么版本的 pandas/numpy?
  • numpy 1.8.1、pandas 0.14、python 2.7.6(默认,2013 年 11 月 10 日,19:24:18)[MSC v.1500 32 位(英特尔)]
  • 澄清一下:上面的解决方案工作正常,只是关心它的性能......

标签: python datetime pandas days


【解决方案1】:

最近修复了性能问题here。这将在 0.14.1 中发布(即将推出,Windows 的开发二进制文件已发布 here,当前发布的内容略微过时且不包含此修复,请稍后再回来查看)。

用于 timedelta 转换的仅供参考的文档是 here

In [1]: s = Series(pd.date_range('20000101',periods=10000).tolist() * 80)

0.14.0

In [3]: %timeit (s-s.min()).astype('timedelta64[D]').astype(int)+1
1 loops, best of 3: 2.9 s per loop

0.14.1

In [12]: %timeit (s-s.min()).astype('timedelta64[D]').astype(int)+1
10 loops, best of 3: 24.7 ms per loop

【讨论】:

  • 哇,好吧,不知道这是一个错误。我不得不承认我不太明白实际上阅读您的链接页面的错误本身是什么,但我想这并不是真正必要的 - 希望尽快发布:-)但问题仍然存在:直接转换甚至是不可能的提高性能更多?就目前而言,已经完成了两次连续的转换(到 timedelta64[D] 并从那里到 int...?所以至少我上面的解决方案是正确的方法做吗?
  • timedelta64 在内部保存为纳秒,因此astype('timedelta64[D]') 返回一个float64 天数系列(您可以有小数天数,仅供参考)。除非您需要 int,否则您不需要转换为 int。在我的示例中,to-int 转换的时间大约是 1.5ms 所以 YMMV。
  • 在针对单日绘制一些随机值时,我希望这些天成为 x 值,但是是的,为此我可能最好简单地使用浮点值。现在我认为将 int 用作完美的圆形/精确值会更干净(因为我的日子不应该是小数),但是使用 float 应该没有问题,或者你看到一个绊脚石吗?
  • 我添加了一个文档链接,它们与您正在做的事情和(s-s.min())/np.timedelta64(1,'D')(numpy 截断)略有不同;几乎相同的性能。
  • 它们实际上是相同的,只是除法被截断而不是给出确切的答案。
猜你喜欢
  • 2018-10-30
  • 2019-08-23
  • 2021-07-18
  • 2017-06-17
  • 1970-01-01
  • 2018-03-03
  • 2016-01-27
相关资源
最近更新 更多