【问题标题】:Comparing numpy array of datetimes with timestamp将numpy的日期时间数组与时间戳进行比较
【发布时间】:2020-04-22 21:59:53
【问题描述】:

我不明白为什么这段代码会引发错误。 '>' 不是矢量化的吗?我可以看到x_month_begin[0,0] > st_d比较没有问题。将不胜感激见解和修复建议。

    import pandas as pd
    import numpy as np
    import datetime




    end_d = pd.to_datetime('23/02/2018', format="%d/%m/%Y")


    x_month_begin = pd.date_range(datetime.datetime(year=end_d.year-1, month=1, day=1), 
                                      datetime.datetime(year=end_d.year+1, month=12, day=1), freq='MS')

    # stacking with each row for each year        
    x_month_begin = np.vstack(np.split(x_month_begin, 3))
    # transposing for each column to be a year
    x_month_begin = np.transpose(x_month_begin)

    st_d = pd.to_datetime('01/2016', format="%m/%Y")

    x_month_begin > st_d

【问题讨论】:

  • 你能分享end_d对象吗?
  • 为什么这段代码会抛出错误。什么错误?
  • 添加了结束日期。

标签: python python-3.x pandas numpy datetime


【解决方案1】:

如果检查对象的类型,问题就会变得清晰。

  1. x_month_begin: 是一个 3 维 numpy 数组 (x_month_begin.shape)
  2. st_d: 是 pandas 时间戳变量

两者不能直接比较。为了比较,你可以这样做:

[y > st_d for x in x_month_begin for y in x ]

【讨论】:

    【解决方案2】:

    所以你从 pandas 结构开始:

    In [133]: x_month_begin                                                         
    Out[133]: 
    DatetimeIndex(['2020-01-01', '2020-02-01', '2020-03-01', '2020-04-01',
                   '2020-05-01', '2020-06-01', '2020-07-01', '2020-08-01',
                   '2020-09-01', '2020-10-01', '2020-11-01', '2020-12-01'],
                  dtype='datetime64[ns]', freq='MS')
    

    和 numpy 数组一样的东西:

    In [134]: x_month_begin.values                                                  
    Out[134]: 
    array(['2020-01-01T00:00:00.000000000', '2020-02-01T00:00:00.000000000',
           '2020-03-01T00:00:00.000000000', '2020-04-01T00:00:00.000000000',
           '2020-05-01T00:00:00.000000000', '2020-06-01T00:00:00.000000000',
           '2020-07-01T00:00:00.000000000', '2020-08-01T00:00:00.000000000',
           '2020-09-01T00:00:00.000000000', '2020-10-01T00:00:00.000000000',
           '2020-11-01T00:00:00.000000000', '2020-12-01T00:00:00.000000000'],
          dtype='datetime64[ns]')
    

    你将它操纵成一个 (n,3) 数组(我怀疑这可以通过重塑和可能的转置更直接地完成):

    In [135]: x_month_begin = np.vstack(np.split(x_month_begin, 3))                 
    In [138]: x_month_begin = np.transpose(x_month_begin)                           
    In [139]: x_month_begin                                                         
    Out[139]: 
    array([['2020-01-01T00:00:00.000000000', '2020-05-01T00:00:00.000000000',
            '2020-09-01T00:00:00.000000000'],
           ['2020-02-01T00:00:00.000000000', '2020-06-01T00:00:00.000000000',
            '2020-10-01T00:00:00.000000000'],
           ['2020-03-01T00:00:00.000000000', '2020-07-01T00:00:00.000000000',
            '2020-11-01T00:00:00.000000000'],
           ['2020-04-01T00:00:00.000000000', '2020-08-01T00:00:00.000000000',
            '2020-12-01T00:00:00.000000000']], dtype='datetime64[ns]')
    In [140]: _.shape                                                               
    Out[140]: (4, 3)
    

    任何方式,现在你的比较:

    In [141]: st_d = pd.to_datetime('01/2016', format="%m/%Y")                      
    In [142]: st_d                                                                  
    Out[142]: Timestamp('2016-01-01 00:00:00')
    In [143]: x_month_begin >st_d                                                   
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-143-30567662e59d> in <module>
    ----> 1 x_month_begin >st_d
    
    pandas/_libs/tslibs/c_timestamp.pyx in pandas._libs.tslibs.c_timestamp._Timestamp.__richcmp__()
    
    TypeError: '<' not supported between instances of 'Timestamp' and 'int'
    

    numpy 数组可以进行&lt; 比较,但它们对于dtypes 的兼容有一定的规则。 (例如,比较字符串和数字不起作用)。另外pandas玩自己的日期和时间游戏,有些格式是内部的,有些兼容numpy的datatime64

    例如,如果我们将您的时间戳转换为等效的 numpy:

    In [144]: st_d.to_numpy()                                                       
    Out[144]: numpy.datetime64('2016-01-01T00:00:00.000000000')
    

    比较有效:

    In [145]: x_month_begin>st_d.to_numpy()                                         
    Out[145]: 
    array([[ True,  True,  True],
           [ True,  True,  True],
           [ True,  True,  True],
           [ True,  True,  True]])
    

    pandas 建立在numpy 之上,或者至少使用numpy 数组来存储其数据。但是没有一个numpy 代码是pandas 知道的。如果给定一个非 numpy 对象,它会天真地尝试转换它,例如

    In [146]: np.asarray(st_d)                                                      
    Out[146]: array(Timestamp('2016-01-01 00:00:00'), dtype=object)
    

    不同于Out[144]。 [146] 是产生错误的转换。

    The original `DatetimeIndex` can be tested against the timestamp.  That's a 'pure' pandas operation.
    
    In [152]: _133>st_d                                                             
    Out[152]: 
    array([ True,  True,  True,  True,  True,  True,  True,  True,  True,
            True,  True,  True])
    

    _133.to_numpy().reshape(-1,4).T 直接给出x_month_begin 数组。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-23
      • 1970-01-01
      • 2017-05-04
      • 1970-01-01
      • 1970-01-01
      • 2014-09-30
      相关资源
      最近更新 更多