【问题标题】:Reading CSV data with yearday column into Pandas as datetime将带有 yearday 列的 CSV 数据作为日期时间读入 Pandas
【发布时间】:2014-07-19 11:24:47
【问题描述】:

我有 CSV 数据,其中以年作为列之一,而不是通常的月份和日期。我花了一个小时,这是我唯一能做的事情:将所有浮点列转换为整数,打印为字符串,然后使用自定义解析例程将字符串转换为日期时间:

from pylab import *
import pandas as pd
import datetime as dt
from StringIO import StringIO

csv = '''Latitude, Longitude, Hours, Minutes, Seconds, YearDay, Year, CruiseID
41.942880, -70.292217, 23, 54, 20, 253, 2011, 11015
41.942865, -70.292160, 23, 54, 22, 253, 2011, 11015
41.942847, -70.292105, 23, 54, 24, 253, 2011, 11015
41.942827, -70.292052, 23, 54, 26, 253, 2011, 11015
41.942803, -70.292002, 23, 54, 28, 253, 2011, 11015

'''

def parse(hr, mn, sec, yearday, yr):
    date_string = '%4.4d %3.3d %2.2d %2.2d %2.2d' % (int(yr), int(yearday), int(hr), int(mn), int(sec))
    return dt.datetime.strptime(date_string, "%Y %j %H %M %S")

df = pd.read_csv(StringIO(csv),skipinitialspace=True,
                 parse_dates={'datetime':['Hours','Minutes','Seconds','YearDay','Year']}, 
                 date_parser=parse, index_col='datetime',skipfooter=1)

这确实给出了正确的结果:

print df
                      Latitude  Longitude  CruiseID
datetime                                           
2011-09-10 23:54:20  41.942880 -70.292217     11015
2011-09-10 23:54:22  41.942865 -70.292160     11015
2011-09-10 23:54:24  41.942847 -70.292105     11015
2011-09-10 23:54:26  41.942827 -70.292052     11015
2011-09-10 23:54:28  41.942803 -70.292002     11015
2011-09-11 00:08:48  41.933332 -70.281817     11015

但是读取这些数据的更简单、更好的方法是什么?

【问题讨论】:

  • 这看起来是个好方法。
  • 哇,好吧!我想我被转换为整数并写出字符串所困扰。我想我可以通过在 read_csv 参数中分配 dtype 来解决整数转换问题,但这并不简单。
  • 啊,是的,你不能做一个更直接的字符串替换......或者''.join((小时,年日,..))。您不必转换为 int 并返回!
  • 安迪,你想在下面发布改进的解决方案,以便人们可以轻松找到它(这样我就可以奖励你积分)?

标签: python datetime csv pandas


【解决方案1】:

直接使用datetime()

示例(未经测试):

def parse(hr, mn, sec, yearday, yr):
   date1 = dt.datetime(year=int(yr), month=1, day=1, hour=int(hr), minute=int(mn), second=int(sec))
   return date1 + dt.timedelta(days=yearday-1)

【讨论】:

  • 我喜欢这个作为strptime 的替代品。不过似乎有点“棘手”。
【解决方案2】:

使用strptime '%j' 格式:

>>> import datetime as dt
>>> dt.strptime('253 2011', '%j %Y')
>>> dt.datetime.strptime('253 2011', '%j %Y')
datetime.datetime(2011, 9, 10, 0, 0)

你也可以直接在strptime中使用逗号格式:

>>> dt.datetime.strptime('23, 54, 20, 253, 2011', '%H, %M, %S, %j, %Y')
datetime.datetime(2011, 9, 10, 23, 54, 20)

请注意,数字需要补零。 (即01 不是1

【讨论】:

  • 我在原始示例中确实使用了 strptime %j 格式——也许我在这里错过了你的建议?
【解决方案3】:

您可以将 parse 函数编写得更简洁一些,而无需进行 int 转换:

def parse(hr, mn, sec, yearday, yr):
          date_string = ' '.join([yr, yearday, hr, mn, sec])
          return dt.datetime.strptime(date_string, "%Y %j %H %M %S")

除此之外,IMO 您的解决方案看起来不错(我认为您确实需要在这里编写自己的解析器)。

【讨论】:

    猜你喜欢
    • 2012-03-11
    • 2013-07-03
    • 2018-12-14
    • 2013-03-11
    • 2021-09-02
    • 2018-07-05
    • 1970-01-01
    • 2012-02-02
    • 2020-08-12
    相关资源
    最近更新 更多