【问题标题】:Parsing dates on different columns and with julian day using Pandas使用 Pandas 解析不同列和朱利安日的日期
【发布时间】:2025-12-11 23:30:01
【问题描述】:

我有一个按如下方式组织的 CSV 文件

   0     1    2     3      4      5      6      7      8     9     10  11
0  42  2012  106  1200 -0.325  0.576 -0.295  31.73  14.80  1096  99.3  55
1  42  2012  106  1200 -0.372  0.499 -0.236  31.74  14.80  1097  99.3  56
2  42  2012  106  1200 -0.372  0.456 -0.212  31.74  14.80  1096  99.3  57
3  42  2012  106  1200 -0.312  0.736 -0.095  31.70  14.81  1097  99.3  58
4  42  2012  106  1200 -0.352  0.707 -0.035  31.66  14.78  1094  99.3  59
5  42  2012  106  1200 -0.518  0.662 -0.152  31.66  14.79  1094  99.3  60
6  42  2012  106  1200 -0.516  0.531 -0.249  31.78  14.79  1094  99.3  61

第 1、2 和 3 列分别是年份、儒略日和 %hour%minute。我正在尝试将这些列解析为日期时间索引,但我似乎做不到。

我尝试了一些东西,最有希望的是来自this answer,所以我写了(假设fname是文件的路径)

dateparse= lambda x: datetime.datetime.strptime(x, '%Y %j %H%M')
pd.read_csv(fname, header=None, parse_dates=[[1,2,3]], date_parser=dateparse)

但这给了我错误

TypeError: <lambda>() takes exactly 1 argument (3 given)

这表明熊猫显然没有像我预期的那样连接第 1,2 和 3 列然后应用解析器函数。如果我只用

阅读 csv
pd.read_csv(fname, header=None, parse_dates=[[1,2,3]])
DATA=data.set_index('1_2_3')

然后我得到

               0      4      5      6      7      8     9     10  11
1_2_3                                                               
2012 106 1200  42 -0.325  0.576 -0.295  31.73  14.80  1096  99.3  55
2012 106 1200  42 -0.372  0.499 -0.236  31.74  14.80  1097  99.3  56
2012 106 1200  42 -0.372  0.456 -0.212  31.74  14.80  1096  99.3  57
2012 106 1200  42 -0.312  0.736 -0.095  31.70  14.81  1097  99.3  58
2012 106 1200  42 -0.352  0.707 -0.035  31.66  14.78  1094  99.3  59
2012 106 1200  42 -0.518  0.662 -0.152  31.66  14.79  1094  99.3  60
2012 106 1200  42 -0.516  0.531 -0.249  31.78  14.79  1094  99.3  61

但索引不被视为日期,它是一个字符串:

DATA.index
Index([u'2012 106 1200', u'2012 106 1200', u'2012 106 1200', u'2012 106 1200', ...], dtype='object')

有什么想法吗?

【问题讨论】:

    标签: python parsing csv datetime pandas


    【解决方案1】:

    使用这样的日期解析器将非常低效。除非您有 ISO 日期,否则通常最好在之后解析。

    但在这里。关键是date_parser 采用的参数数量与您传递的参数数量相同(在本例中为 3)。

    In [12]: dateparse = lambda a,b,c: datetime.datetime.strptime(' '.join([a,b,c]), '%Y %j %H%M')
    
    In [13]: pd.read_csv(StringIO(data), 
         header=None, 
         parse_dates=[[2,3,4]], 
         sep='\s+',skiprows=1, 
         date_parser=dateparse)
    Out[13]: 
                    2_3_4  0   1      5      6      7      8      9    10    11  12
    0 2012-04-15 12:00:00  0  42 -0.325  0.576 -0.295  31.73  14.80  1096  99.3  55
    1 2012-04-15 12:00:00  1  42 -0.372  0.499 -0.236  31.74  14.80  1097  99.3  56
    2 2012-04-15 12:00:00  2  42 -0.372  0.456 -0.212  31.74  14.80  1096  99.3  57
    3 2012-04-15 12:00:00  3  42 -0.312  0.736 -0.095  31.70  14.81  1097  99.3  58
    4 2012-04-15 12:00:00  4  42 -0.352  0.707 -0.035  31.66  14.78  1094  99.3  59
    5 2012-04-15 12:00:00  5  42 -0.518  0.662 -0.152  31.66  14.79  1094  99.3  60
    6 2012-04-15 12:00:00  6  42 -0.516  0.531 -0.249  31.78  14.79  1094  99.3  61
    

    这里还有一些方法

    In [45]: df = read_csv(StringIO(data),sep='\s+')
    
    In [46]: df
    Out[46]: 
        0     1    2     3      4      5      6      7      8     9    10  11
    0  42  2012  106  1200 -0.325  0.576 -0.295  31.73  14.80  1096  99.3  55
    1  42  2012  106  1200 -0.372  0.499 -0.236  31.74  14.80  1097  99.3  56
    2  42  2012  106  1200 -0.372  0.456 -0.212  31.74  14.80  1096  99.3  57
    3  42  2012  106  1200 -0.312  0.736 -0.095  31.70  14.81  1097  99.3  58
    4  42  2012  106  1200 -0.352  0.707 -0.035  31.66  14.78  1094  99.3  59
    5  42  2012  106  1200 -0.518  0.662 -0.152  31.66  14.79  1094  99.3  60
    6  42  2012  106  1200 -0.516  0.531 -0.249  31.78  14.79  1094  99.3  61
    

    强制返回字符串、连接和解析。

    In [47]: pd.to_datetime(df['1'].astype(str) + ' ' + df['2'].astype(str) + ' ' + df['3'].astype(str), format='%Y %j %H%M')
    Out[47]: 
    0   2012-04-15 12:00:00
    1   2012-04-15 12:00:00
    2   2012-04-15 12:00:00
    3   2012-04-15 12:00:00
    4   2012-04-15 12:00:00
    5   2012-04-15 12:00:00
    6   2012-04-15 12:00:00
    dtype: datetime64[ns]
    

    另一种方法。

    In [48]: pd.to_datetime(df['1'],format='%Y') + pd.to_timedelta(df['2'],unit='d') + pd.to_timedelta(df['3']/100,unit='h') + pd.to_timedelta(df['3']%100,unit='m') - Timedelta('1d')
    Out[48]: 
    0   2012-04-15 12:00:00
    1   2012-04-15 12:00:00
    2   2012-04-15 12:00:00
    3   2012-04-15 12:00:00
    4   2012-04-15 12:00:00
    5   2012-04-15 12:00:00
    6   2012-04-15 12:00:00
    dtype: datetime64[ns]
    

    【讨论】: