使用pandas读取带有时间戳列的csv文件

47

在进行操作时:

import pandas
x = pandas.read_csv('data.csv', parse_dates=True, index_col='DateTime', 
                                names=['DateTime', 'X'], header=None, sep=';')

使用这个 data.csv 文件:

1449054136.83;15.31
1449054137.43;16.19
1449054138.04;19.22
1449054138.65;15.12
1449054139.25;13.12

(第一列是UNIX时间戳,即自1970年1月1日以来经过的秒数),当我使用x.resample('15S')对数据进行每15秒重新采样时,会出现以下错误:

TypeError: Only valid with DatetimeIndex, TimedeltaIndex or PeriodIndex

就好像“datetime”信息还没有被解析一样:

                 X
DateTime      
1.449054e+09  15.31                
1.449054e+09  16.19
...

如何使用 pandas 模块导入存储为时间戳的 .CSV 文件?

一旦成功导入 CSV,如何访问日期大于 2015-12-02 12:02:18 的行?


我认为这个问题是 https://dev59.com/8GjWa4cB1Zd3GeqPmgMt 的重复。 - Wirawan Purwanto
5个回答

43
使用 to_datetime 函数,传递 unit='s' 来解析时间戳,这样会更快速:
In [7]:
pd.to_datetime(df.index, unit='s')

Out[7]:
DatetimeIndex(['2015-12-02 11:02:16.830000', '2015-12-02 11:02:17.430000',
               '2015-12-02 11:02:18.040000', '2015-12-02 11:02:18.650000',
               '2015-12-02 11:02:19.250000'],
              dtype='datetime64[ns]', name=0, freq=None)

时间:

In [9]:

import time
%%timeit
import time
def date_parser(string_list):
    return [time.ctime(float(x)) for x in string_list]
​
df = pd.read_csv(io.StringIO(t), parse_dates=[0],  sep=';', 
                 date_parser=date_parser, 
                 index_col='DateTime', 
                 names=['DateTime', 'X'], header=None)
100 loops, best of 3: 4.07 ms per loop

并且

In [12]:
%%timeit
t="""1449054136.83;15.31
1449054137.43;16.19
1449054138.04;19.22
1449054138.65;15.12
1449054139.25;13.12"""
df = pd.read_csv(io.StringIO(t), header=None, sep=';', index_col=[0])
df.index = pd.to_datetime(df.index, unit='s')
100 loops, best of 3: 1.69 ms per loop

所以在这个小数据集上使用to_datetime比其他方法快2倍以上,我预计在更大的数据集上它会更好。


2
我不确定为什么,但是在 unit='s' 的情况下,pandas 会失去微秒精度(pandas 0.18.1)。传递 df.ts*1000, unit='ms' 可以解决这个问题。 - Mikhail Korobov
1
@MikhailKorobov,你需要发布原始代码和演示代码,以便我能够进行评论。 - EdChum

33

我的解决方案与Mike的类似:

import pandas
import datetime
def dateparse (time_in_secs):    
    return datetime.datetime.fromtimestamp(float(time_in_secs))

x = pandas.read_csv('data.csv',delimiter=';', parse_dates=True,date_parser=dateparse, index_col='DateTime', names=['DateTime', 'X'], header=None)

out = x.truncate(before=datetime.datetime(2015,12,2,12,2,18))

非常感谢!您有如何访问日期> 2015-12-02 12:02:18的“x”行的示例吗?(即按日期过滤) - Basj
使用Pandas解决方案非常简单。我已经编辑了解决方案。 - Budo Zindovic
你知道为什么我无法像这里建议的那样使用它吗?我应该能够执行x.ix['2015-12-02 12:02:18':'2015-12-31 23:59:59']x.loc[...],为什么它不像那里建议的那样工作呢?是因为日期时间列不是索引吗?如何使其成为“索引”? - Basj
我将此作为参考,因为我发现它是解释问题和解决方案最有帮助的资源:https://dev59.com/-mEi5IYBdhLWcg3wb7-O - Reddspark
EdChum的下面的答案在大型CSV文件上快了3倍以上。 - Sabar

7

最简单的方法是:

df = pd.read_csv(f, parse_dates=['datecolumn', 'datecolumn1'], infer_datetime_format=True)

感谢Vetri和@RiveN的帮助,但是我无法将其应用于我问题中提供的示例数据。我尝试了所有可能的变体:df = pd.read_csv(f, parse_dates=['dt'], names=['dt', 'X'], infer_datetime_format=True, sep=';', header=None),但它不起作用。您能否请添加用于包含问题中行的无标题CSV文件的代码?谢谢! - Basj

5

你可以自行解析日期:

import time
import pandas as pd

def date_parser(string_list):
    return [time.ctime(float(x)) for x in string_list]

df = pd.read_csv('data.csv', parse_dates=[0],  sep=';', 
                 date_parser=date_parser, 
                 index_col='DateTime', 
                 names=['DateTime', 'X'], header=None)

结果如下:
>>> df
                        X
DateTime                  
2015-12-02 12:02:16  15.31
2015-12-02 12:02:17  16.19
2015-12-02 12:02:18  19.22
2015-12-02 12:02:18  15.12
2015-12-02 12:02:19  13.12

非常感谢!那么(对于问题的第二部分),如何访问df的子部分,其中日期> 2015-12-02 12:02:18?(即进行过滤) - Basj

0
@EdChum的解决方案经过简化后,适用于我的数据集:
x = pd.read_csv('data.csv', 
                 parse_dates=True, 
                 date_parser=pd.to_datetime,
                 index_col='DateTime', 
                 names=['DateTime', 'X'], 
                 header=None, 
                 sep=';')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接