使用熊猫读取带有时间戳列的 csv

Posted

技术标签:

【中文标题】使用熊猫读取带有时间戳列的 csv【英文标题】:Reading a csv with a timestamp column, with pandas 【发布时间】:2016-03-11 09:30:22 【问题描述】:

做的时候:

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

好像“日期时间”信息没有被解析:

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

如何使用 pandas 模块导入将日期存储为时间戳的 .CSV?

那么一旦我能够导入 CSV,如何访问日期 > 2015-12-02 12:02:18 的行?

【问题讨论】:

我认为这个问题与***.com/questions/12251483/… 重复。 【参考方案1】:

你可以自己解析日期:

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

【讨论】:

非常感谢!然后(对于问题的第二部分),如何访问日期为 > 2015-12-02 12:02:18 的df 的子部分? (即过滤)【参考方案2】:

我的解决方案与 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 行? (即按日期过滤) 使用 Pandas 的解决方案相当简单。我已经编辑了解决方案。 你知道为什么我无法按照here 的建议获得吗?我应该可以做到x.ix['2015-12-02 12:02:18':'2015-12-31 23:59:59']x.loc[...],为什么它没有按照那里的建议工作?是因为日期时间列不是索引吗?那么如何让它成为“索引”呢? 我引用了这个,因为我发现它是解释问题和解决方案最有用的资源:@​​987654322@ EdChum 下面的答案在大型 CSV 文件上速度提高了 3 倍以上。【参考方案3】:

使用to_datetime 并传递unit='s' 将单位解析为unix 时间戳,这样会更快:

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 倍以上,我希望它的扩展性比其他方法好得多

【讨论】:

我不知道为什么,但是使用 unit='s' 时,熊猫会失去微秒精度(熊猫 0.18.1)。传递df.ts*1000, unit='ms' 有帮助。 @MikhailKorobov 你必须发布原始代码和演示这一点的代码,否则我无法评论【参考方案4】:

最简单的方法:

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 文件的代码,该文件没有包含问题中行的标题?谢谢!

以上是关于使用熊猫读取带有时间戳列的 csv的主要内容,如果未能解决你的问题,请参考以下文章

spark scala比较具有时间戳列的数据帧

在熊猫中使用单独的时间戳列进行最小/最大分组[重复]

将UTC时间戳转换为熊猫中的本地时区问题

从 csv 中读取 ms 中的时间戳,在 Matlab 中以科学格式显示

如何读取带有时间戳字段的 csv?

将事件流式传输到大查询 - 数据流 - 将 **epoch 时间戳** (int) 插入时间戳列的最佳方式