【问题标题】:What's the difference between changing datetime string to datetime by pd.to_datetime & datetime.strptime()通过 pd.to_datetime 和 datetime.strptime() 将日期时间字符串更改为日期时间有什么区别
【发布时间】:2020-11-22 21:28:12
【问题描述】:

我有一个看起来与此类似的 df(缩短的版本,行数更少):

    Time (EDT)          Open    High    Low     Close
0   02.01.2006 19:00:00 0.85224 0.85498 0.85224 0.85498
1   02.01.2006 20:00:00 0.85498 0.85577 0.85423 0.85481
2   02.01.2006 21:00:00 0.85481 0.85646 0.85434 0.85646
3   02.01.2006 22:00:00 0.85646 0.85705 0.85623 0.85651
4   02.01.2006 23:00:00 0.85643 0.85691 0.85505 0.85653
5   03.01.2006 00:00:00 0.85653 0.8569  0.85601 0.85626
6   03.01.2006 01:00:00 0.85626 0.85653 0.85524 0.8557
7   03.01.2006 02:00:00 0.85558 0.85597 0.85486 0.85597
8   03.01.2006 03:00:00 0.85597 0.85616 0.85397 0.8548
9   03.01.2006 04:00:00 0.85469 0.85495 0.8529  0.85328
10  03.01.2006 05:00:00 0.85316 0.85429 0.85222 0.85401
11  03.01.2006 06:00:00 0.85401 0.8552  0.853   0.8552
12  03.01.2006 07:00:00 0.8552  0.8555  0.85319 0.85463
13  03.01.2006 08:00:00 0.85477 0.85834 0.8545  0.85788
14  03.01.2006 09:00:00 0.85788 0.85838 0.85341 0.85416
15  03.01.2006 10:00:00 0.8542  0.8542  0.85006 0.85111
16  03.01.2006 11:00:00 0.85115 0.85411 0.85    0.85345
17  03.01.2006 12:00:00 0.85337 0.85432 0.8526  0.85413
18  03.01.2006 13:00:00 0.85413 0.85521 0.85363 0.85363
19  03.01.2006 14:00:00 0.85325 0.8561  0.85305 0.85606
20  03.01.2006 15:00:00 0.8561  0.85675 0.85578 0.85599

我需要将日期字符串转换为日期时间,然后将日期列设置为索引,然后重新采样。当我使用方法 1 时,我无法正确重新采样,它重新采样的数据是错误的,它会创建额外的未来日期。假设我的最后一个日期是 2018-11,我会看到 2018-12 类似的东西。

方法一:

df['Time (EDT)'] = pd.to_datetime(df['Time (EDT)'])  <---- this takes long also, because theres 90000 rows
df.set_index('Time (EDT)', inplace=True)

ohlc_dict = {'Open':'first','High':'max', 'Low':'min','Close'}
df=df.resample'4H', base=17, closed='left', label='left').agg(ohlc_dict)

结果:

    Time (EDT)      Open    High    Low     Close
    1/1/2006 21:00  0.86332 0.86332 0.86268 0.86321
    1/2/2006 1:00   0.86321 0.86438 0.86111 0.86164
    1/2/2006 5:00   0.86164 0.86222 0.8585  0.86134
    1/2/2006 9:00   0.86149 0.86297 0.85695 0.85793
    1/2/2006 13:00  0.85801 0.85947 0.85759 0.8591
    1/2/2006 17:00  0.8591  0.86034 0.85757 0.85825
    1/2/2006 21:00  0.85825 0.85969 0.84377 0.84412
    1/3/2006 1:00   0.84445 0.8468  0.84286 0.84642
    1/3/2006 5:00   0.84659 0.8488  0.84494 0.84872
    1/3/2006 9:00   0.84829 0.84915 0.84271 0.84416
    1/3/2006 13:00  0.84372 0.8453  0.84346 0.84423
    1/3/2006 17:00  0.84426 0.84693 0.84426 0.84516
    1/3/2006 21:00  0.84523 0.8458  0.84442 0.84579

当我使用方法 2 时,它会正确重新采样

方法二:

def to_datetime_obj(date_string):
     datetime_obj = datetime.strptime(date_string[:], '%d.%m.%Y %H:%M:%S')
     return datetime_obj

datetime_objs = None
date_list = df['Time (EDT)'].tolist()
datetime_objs=list(map(to_datetime_obj, date_list)) <--- this is faster also
df.iloc[:,:1] = datetime_objs
df.set_index('Time (EDT)', inplace=True)

ohlc_dict = {'Open':'first','High':'max', 'Low':'min','Close'}
df=df.resample'4H', base=17, closed='left', label='left').agg(ohlc_dict)

结果:

Time (EDT)      Open    High    Low     Close
1/2/2006 17:00  0.85224 0.85577 0.85224 0.85481
1/2/2006 21:00  0.85481 0.85705 0.85434 0.85626
1/3/2006 1:00   0.85626 0.85653 0.8529  0.85328
1/3/2006 5:00   0.85316 0.85834 0.85222 0.85788
1/3/2006 9:00   0.85788 0.85838 0.85    0.85413
1/3/2006 13:00  0.85413 0.85675 0.85305 0.85525
1/3/2006 17:00  0.85525 0.85842 0.85502 0.85783
1/3/2006 21:00  0.85783 0.85898 0.85736 0.85774
1/4/2006 1:00   0.85774 0.85825 0.8558  0.85595
1/4/2006 5:00   0.85595 0.85867 0.85577 0.85839
1/4/2006 9:00   0.85847 0.85981 0.85586 0.8578
1/4/2006 13:00  0.85773 0.85886 0.85597 0.85653
1/4/2006 17:00  0.85653 0.85892 0.85642 0.8584
1/4/2006 21:00  0.8584  0.85863 0.85658 0.85715
1/5/2006 1:00   0.85715 0.8588  0.85641 0.85791
1/5/2006 5:00   0.85803 0.86169 0.85673 0.86065
  1. 方法 1 和方法 2 的 df.index 在重采样之前在视觉上是相同的。
  2. 他们都是pandas.core.indexes.datetimes.DatetimeIndex
  3. 但是当我比较它们时,它们实际上是不同的method1_df.index != method2_df.index

这是为什么呢?怎么修?谢谢。

【问题讨论】:

    标签: pandas datetime datetimeindex string-to-datetime


    【解决方案1】:

    令人惊讶的是,用 Cython 编写的矢量化方法 (pd.to_datetime) 比纯 Python 方法 (datetime.strptime) 慢。

    您可以将格式指定为pd.to_datetime,这会大大加快速度:

    pd.to_datetime(df['Time (EDT)'], format='%d.%m.%Y %H:%M:%S')
    

    对于您的第二个问题,我认为这可能与您的字符串数据中的日期和月份的顺序有关。您是否确认这两种方法实际上给您相同的日期时间?

    s1 = pd.to_datetime(df['Time (EDT)'])
    s2 = pd.Series(map(to_datetime_obj, date_list))
    (s1 == s2).all()
    

    【讨论】:

    • 它们在视觉上是相同的,但正如我在比较时所说的那样,它们是不同的。哦...也许如果正在使用 to_datetime,它会将其视为月份日期。但我的数据源是日期-月份。
    • 然后找出这些差异:cmp = method1_df.index == method2_df.index; cmp[~cmp]。目视检查只能告诉你部分情况
    • 是否可以直接在那里读取csv、parse_date并指定格式?
    • 你可以在你的pd.read_csv调用中设置dayfirst=True
    • 为什么pd.to_datetime 应该比datetime.strptime 慢?对于没有定义格式的少量元素,这可能是正确的,但对于更大的尺寸,比如 100k 个元素,我的赌注是pandas
    猜你喜欢
    • 1970-01-01
    • 2011-05-26
    • 2018-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-29
    • 1970-01-01
    • 2015-09-17
    相关资源
    最近更新 更多