【问题标题】:Python Pandas Series of Datetimes to Seconds Since the Epoch自纪元以来的 Python Pandas 系列日期时间到秒数
【发布时间】:2013-11-02 10:11:14
【问题描述】:

本着this answer 的精神,我尝试了以下方法将日期时间的DataFrame 列转换为自纪元以来的秒数列。

df['date'] = (df['date']+datetime.timedelta(hours=2)-datetime.datetime(1970,1,1))
df['date'].map(lambda td:td.total_seconds())

第二个命令导致以下我不明白的错误。对这里可能发生的事情有任何想法吗?我用 apply 替换了 map ,但这无济于事。

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-99-7123e823f995> in <module>()
----> 1 df['date'].map(lambda td:td.total_seconds())

/Users/cpd/.virtualenvs/py27-ipython+pandas/lib/python2.7/site-packages/pandas-0.12.0_937_gb55c790-py2.7-macosx-10.8-x86_64.egg/pandas/core/series.pyc in map(self, arg, na_action)
   1932             return self._constructor(new_values, index=self.index).__finalize__(self)
   1933         else:
-> 1934             mapped = map_f(values, arg)
   1935             return self._constructor(mapped, index=self.index).__finalize__(self)
   1936 

/Users/cpd/.virtualenvs/py27-ipython+pandas/lib/python2.7/site-packages/pandas-0.12.0_937_gb55c790-py2.7-macosx-10.8-x86_64.egg/pandas/lib.so in pandas.lib.map_infer (pandas/lib.c:43628)()

<ipython-input-99-7123e823f995> in <lambda>(td)
----> 1 df['date'].map(lambda td:td.total_seconds())

AttributeError: 'float' object has no attribute 'total_seconds'

【问题讨论】:

  • 看来“日期”列一开始可能不是 datetime64?
  • 该列是否包含任何缺失值?缺失值通常会导致 pandas Series 被转换为浮点数,当您尝试将它们解释为日期时间时会导致奇怪。
  • @Abe 确实你是对的。原来在一些记录中有一些缺失的数据。不是我预期的……Ack。

标签: python datetime pandas


【解决方案1】:

更新:

在 0.15.0 Timedeltas 成为成熟的 dtype。

所以这成为可能(以及下面的方法)

In [45]: s = Series(pd.timedelta_range('1 day',freq='1S',periods=5))                         

In [46]: s.dt.components
Out[46]: 
   days  hours  minutes  seconds  milliseconds  microseconds  nanoseconds
0     1      0        0        0             0             0            0
1     1      0        0        1             0             0            0
2     1      0        0        2             0             0            0
3     1      0        0        3             0             0            0
4     1      0        0        4             0             0            0

In [47]: s.astype('timedelta64[s]')
Out[47]: 
0    86400
1    86401
2    86402
3    86403
4    86404
dtype: float64

原答案:

我看到你在 master 上(0.13 很快就会出来), 所以假设你有 numpy >= 1.7。做这个。文档见here(这是变频)

In [5]: df = DataFrame(dict(date = date_range('20130101',periods=10)))

In [6]: df
Out[6]: 
                 date
0 2013-01-01 00:00:00
1 2013-01-02 00:00:00
2 2013-01-03 00:00:00
3 2013-01-04 00:00:00
4 2013-01-05 00:00:00
5 2013-01-06 00:00:00
6 2013-01-07 00:00:00
7 2013-01-08 00:00:00
8 2013-01-09 00:00:00
9 2013-01-10 00:00:00

In [7]: df['date']+timedelta(hours=2)-datetime.datetime(1970,1,1)
Out[7]: 
0   15706 days, 02:00:00
1   15707 days, 02:00:00
2   15708 days, 02:00:00
3   15709 days, 02:00:00
4   15710 days, 02:00:00
5   15711 days, 02:00:00
6   15712 days, 02:00:00
7   15713 days, 02:00:00
8   15714 days, 02:00:00
9   15715 days, 02:00:00
Name: date, dtype: timedelta64[ns]

In [9]: (df['date']+timedelta(hours=2)-datetime.datetime(1970,1,1)) / np.timedelta64(1,'s')
Out[9]: 
0    1357005600
1    1357092000
2    1357178400
3    1357264800
4    1357351200
5    1357437600
6    1357524000
7    1357610400
8    1357696800
9    1357783200
Name: date, dtype: float64

包含的值是np.timedelta64[ns] 对象,它们没有与timedelta 对象相同的方法,所以没有total_seconds()

In [10]: s = (df['date']+timedelta(hours=2)-datetime.datetime(1970,1,1))

In [11]: s[0]
Out[11]: numpy.timedelta64(1357005600000000000,'ns')

您可以将它们键入为 int,然后返回 ns 单位。

In [12]: s[0].astype(int)
Out[12]: 1357005600000000000

您也可以这样做(但仅限于单个单元元素)。

In [18]: s[0].astype('timedelta64[s]')
Out[18]: numpy.timedelta64(1357005600,'s')

【讨论】:

  • 完美的杰夫,谢谢!一旦删除了缺少数据的行,我就可以直接将其应用于新问题。 ;-)
  • 您不需要删除缺失值(NaT);他们将返回为 nan
  • 我现在没有时间编辑(和重新验证)答案,但实际上 0.13 版现在允许将“astype”操作应用于整个系列。请参阅 pandas.pydata.org/pandas-docs/stable/…pandas.pydata.org/pandas-docs/stable/whatsnew.html 并在页面上查找“astype”。
  • 我正在寻找一种将Timedeltas 的Series 转换为seconds 以进行绘图的方法。您使用/ pd.Timedelta(seconds=1) 的方法很好。 Stiil,我想知道是否有更好的方法。你怎么看?
  • 这个答案实际上已经过时了; Timedeltas 在 0.15.0 中成为完全成熟的类型。我将添加另一种方法。
猜你喜欢
  • 2016-08-12
  • 2012-08-24
  • 1970-01-01
  • 2011-08-31
  • 2021-07-03
  • 2023-03-27
  • 2019-12-04
  • 1970-01-01
  • 2016-04-17
相关资源
最近更新 更多