【问题标题】:Pandas DateTimeIndex熊猫日期时间索引
【发布时间】:2014-06-30 07:17:37
【问题描述】:

我的数据框需要有一个 DateTimeIndex。问题是我的源文件。 Date 标头是 Date(dd-mm-yy),但实际日期数据的格式为 dd:mm:yy (24:06:1970) 等。我有很多源文件,因此手动更改标头会很繁琐,而且不好的编程习惯。如何从 python 中解决这个问题?

也许创建一个源文件的副本打开它,搜索日期标题,更改它然后关闭它?我是 python 新手,所以我不确定这是否是做事的最佳方式,如果是,我该如何实现这样的代码?

目前我有这个;

df = pd.read_csv('test.csv',
                    skiprows = 4,
                    parse_dates = {'stamp':[0,1]},
                    na_values = 'NaN',                    
                    index_col = 'stamp'
                 )

其中第 0 列是相关日期列,第 1 列是时间列。 我没有收到任何错误消息,只是错误的数据。

抱歉,我应该添加相关 csv 文件的 sn-p。我现在在下面提供了它;

some stuff I dont want 
some stuff I dont want 
some stuff I dont want 
some stuff I dont want 
Date(dd-mm-yy),Time(hh:mm:ss),Julian_Day
01:07:2013,05:40:41,182.236586,659,1638.400000
01:07:2013,05:44:03,182.238924,659,1638.400000
01:07:2013,05:47:48,182.241528,659,1638.400000
01:07:2013,05:52:21,182.244687,659,1638.400000

【问题讨论】:

  • 您能否提供一个示例,其中包含要读取的 csv 数据以及您收到的错误消息?
  • fyi,pandas 并不关心源文件的标题中关于日期格式的内容。

标签: python datetime pandas


【解决方案1】:

我认为主要问题是标题行Date(dd-mm-yy), Time(hh:mm:ss), Julian_Day 似乎只指定了一些列名。 Pandas 无法推断如何处理其他数据。

尝试跳过文件的列名行并传递pandas 列列表names 并定义您自己的date_parser

def my_parser(date, time):
    import datetime
    DATE_FORMAT = '%d:%m:%Y'
    TIME_FORMAT = '%H:%M:%S'
    date = datetime.datetime.strptime(date, DATE_FORMAT)
    time_weird_date = datetime.datetime.strptime(time, TIME_FORMAT)
    return datetime.datetime.combine(date, time_weird_date.time())

import pandas as pd
from cStringIO import StringIO

data = """\
some stuff I dont want 
some stuff I dont want 
some stuff I dont want 
some stuff I dont want 
Date(dd-mm-yy),Time(hh:mm:ss),Julian_Day
01:07:2013,05:40:41,182.236586,659,1638.400000
01:07:2013,05:44:03,182.238924,659,1638.400000
01:07:2013,05:47:48,182.241528,659,1638.400000
01:07:2013,05:52:21,182.244687,659,1638.400000
"""  

pd.read_csv(StringIO(data), skiprows=5, index_col=0, 
            parse_dates={'datetime':['date', 'time']}, 
            names=['date','time', 'Julian_Day', 'col_2', 'col_3'],
            date_parser=my_parser)

这应该给你你想要的。

正如您所说,您是 python 新手,我应该补充一点,cStringIO import StringIOdata = """...StringIO(data) 部分只是为了让我可以以可运行的形式将数据直接包含在此答案中。你只需要在你自己的代码中使用pd.read_csv(my_data_filename, ...

【讨论】:

  • 还可以将date_parser 传递给read_csv,它可以处理奇怪的日期格式。
  • 是的,谢谢@U2EF1,我没有发现默认日期到今天。现在使用有效的解析器修复。
  • 似乎应该有更好的方法来处理时间字段,而不是使其成为具有一些奇怪默认日期的 datetime 对象。拥有datetime.time.strptime() 将是理想的,但没有这样的方法。导入time 模块并进行强制转换似乎也很丑陋,我并不是说模块名称与 my_parser 的第二个参数冲突
【解决方案2】:

你的日期真的很奇怪,你应该把它们都修好。如果由于某种原因您真的无法在磁盘上修复它们,我想您可以内联:

import re
from StringIO import StringIO
s = open('test.csv').read()
def rep(m):
    return '%s-%s-%sT' % (m.group('YY'), m.group('mm'), m.group('dd'))
s = re.sub(r'^(?P<dd>\d\d):(?P<mm>\d\d):(?P<YY>\d{4}),', rep, s, flags=re.M)
df = pd.read_csv(StringIO(s), skiprows=5, index_col=0, 
                 names=['time', 'Julian_Day', 'col_2', 'col_3'])

这只是采用像01:07:2013,05:40:41 这样的奇怪日期并将它们格式化为像2013-07-01T05:40:41 这样的ISO 样式。那么熊猫就可以正常对待它们了。请记住,这些将采用 UTC。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-20
    • 2019-02-19
    • 1970-01-01
    • 2023-01-12
    • 2019-06-27
    • 1970-01-01
    • 2017-02-09
    • 2017-05-22
    相关资源
    最近更新 更多