用于解析pandas中POSIX时间戳的惯用法?

时间:2012-09-03 16:37:26

标签: python numpy pandas

我有一个csv文件,其时间列表示POSIX时间戳,以毫秒为单位。当我在pandas中读取它时,它正确地将其读作Int64,但我想将其转换为DatetimeIndex。现在我首先将它转换为datetime对象,然后将其转换为DatetimeIndex。

In [20]: df.time.head()

Out[20]: 
0    1283346000062
1    1283346000062
2    1283346000062
3    1283346000062
4    1283346000300
Name: time

In [21]: map(datetime.fromtimestamp, df.time.head()/1000.)
Out[21]: 
[datetime.datetime(2010, 9, 1, 9, 0, 0, 62000),
 datetime.datetime(2010, 9, 1, 9, 0, 0, 62000),
 datetime.datetime(2010, 9, 1, 9, 0, 0, 62000),
 datetime.datetime(2010, 9, 1, 9, 0, 0, 62000),
 datetime.datetime(2010, 9, 1, 9, 0, 0, 300000)]

In [22]: pandas.DatetimeIndex(map(datetime.fromtimestamp, df.time.head()/1000.))
Out[22]: 
<class 'pandas.tseries.index.DatetimeIndex'>
[2010-09-01 09:00:00.062000, ..., 2010-09-01 09:00:00.300000]
Length: 5, Freq: None, Timezone: None

这是否有惯用的方式?更重要的是,这是在pandas中存储非唯一时间图的推荐方法吗?

2 个答案:

答案 0 :(得分:6)

您可以将转换器与read_csv结合使用。

In [423]: d = """\
timestamp data
1283346000062 a
1283346000062 b
1283346000062 c
1283346000062 d
1283346000300 e
"""

In [424]: fromtimestamp = lambda x:datetime.fromtimestamp(int(x) / 1000.)

In [425]: df = pandas.read_csv(StringIO(d), sep='\s+', converters={'timestamp': fromtimestamp}).set_index('timestamp')

In [426]: df.index
Out[426]:
<class 'pandas.tseries.index.DatetimeIndex'>
[2010-09-01 15:00:00.062000, ..., 2010-09-01 15:00:00.300000]
Length: 5, Freq: None, Timezone: None

In [427]: df
Out[427]:
                           data
timestamp
2010-09-01 15:00:00.062000    a
2010-09-01 15:00:00.062000    b
2010-09-01 15:00:00.062000    c
2010-09-01 15:00:00.062000    d
2010-09-01 15:00:00.300000    e

答案 1 :(得分:5)

在内部,Timestamps存储在int中,代表纳秒。他们使用numpy datetime/timedelta。时间戳的问题在于它们以ms精度,你已经知道,因为你除以1000.在这种情况下,它更容易astype('M8 [ms]')。它本质上是将这些整数视为具有ms精度的datetime-ints。

In [21]: int_arr
Out[21]: 
array([1283346000062, 1283346000062, 1283346000062, 1283346000062,
       1283346000300])

In [22]: int_arr.astype('M8[ms]')
Out[22]: 
array(['2010-09-01T09:00:00.062-0400', '2010-09-01T09:00:00.062-0400',
       '2010-09-01T09:00:00.062-0400', '2010-09-01T09:00:00.062-0400',
       '2010-09-01T09:00:00.300-0400'], dtype='datetime64[ms]')

Pandas将假设任何常规int数组都在M8 [ns]中。将正确解释具有datetime64 dtype的数组。您可以通过访问它的asi8属性来查看DatetimeIndex的M8 [ns]表示。

[编辑]我意识到这不会直接帮助你使用read_csv。我以为我会抛弃如何在时间戳数组之间快速转换。