【问题标题】:Pandas: Biggest index smaller then a datePandas:比日期更小的最大索引
【发布时间】:2016-02-27 03:55:55
【问题描述】:

给定以下示例 Pandas DataFrame x

             a    b
2014-08-07   0.1  2.0
2014-08-18   0.2  4.0
2014-12-16   0.3  0.0
2015-01-16   0.4  2.3
2015-02-16   0.5  2.1
2015-03-18   0.6  7.0

索引的类型为datetime.date

我想编写一个函数,它接受datetime.datetime 类型的参数start,这样它就可以为我提供小于start 的最大索引。

例如,对于start = datetime.datetime(2015, 1, 20, 17, 30),小于start 的最大索引是2015-01-16

这将为我提供ab 的最新更改,即x.loc[dt(2015,1,16)]

【问题讨论】:

  • 由于某种原因 np.searchsorted 不起作用,但这样做:df.index[df.index < start][-1]
  • 如果你可以按时间对项目进行排序,你可以使用二分搜索/二分法在 log(n) 时间内找到它。

标签: python datetime pandas indexing dataframe


【解决方案1】:

这是我使用 TimeSeries 的解决方案,但对于 DataFrame 是相同的。

基本上它迭代 df,每次迭代检查日期是否大于“开始”,如果不是,则将刚刚检查的日期保存为“上一个”,如果是,则“上一个”是你的结果。

import pandas as pd
import datetime

df = pd.TimeSeries({'2014-08-07': ['0.1', '2.0'],
                    '2014-08-18': ['0.2', '4.0'],
                    '2014-12-16': ['0.3', '0.0'],
                    '2015-01-16': ['0.4', '2.3'],
                    '2015-02-16': ['0.5', '2.1'],
                    '2015-03-18': ['0.6', '7.0']})

start = datetime.datetime(2015, 1, 20, 17, 30)
result = False
previous_i = False

for i,row in df.iteritems():
    if pd.to_datetime(i) >= start:
        result = previous_i
        break # you don't need to check further
    else:
        previous_i = i

print(result)


>>> 2015-01-16

【讨论】:

    【解决方案2】:
    x[:start.date()].ix[-1, :]
    

    为 Pandas Series 提供所需索引中的条目。

    【讨论】:

      【解决方案3】:

      测试解决方案:

      Out[4]: 
                    a    b
      2014-08-07  0.1  2.0
      2014-08-18  0.2  4.0
      2014-12-16  0.3  0.0
      2015-01-16  0.4  2.3
      2015-02-16  0.5  2.1
      2015-03-18  0.6  7.0
      
      In [5]: %timeit df[df.index < pd.to_datetime("2015-09-01")].ix[-1, :]
      The slowest run took 5.15 times longer than the fastest. This could mean that an intermediate result is being cached 
      1000 loops, best of 3: 620 µs per loop
      
      In [6]: %timeit df.iloc[:df.index.values.searchsorted(np.datetime64("2015-09-01"))].ix[-1, :]
      The slowest run took 5.53 times longer than the fastest. This could mean that an intermediate result is being cached 
      1000 loops, best of 3: 293 µs per loop
      
      In [7]: %timeit df[:pd.to_datetime("2015-09-01")].ix[-1, :]
      The slowest run took 5.66 times longer than the fastest. This could mean that an intermediate result is being cached 
      1000 loops, best of 3: 450 µs per loop
      
      __main__:6: FutureWarning: TimeSeries is deprecated. Please use Series
      In [10]: %timeit alecsolution(df)
      1000 loops, best of 3: 503 µs per loop
      

      我认为最快的是:

      df.iloc[:df.index.values.searchsorted(np.datetime64("2015-09-01"))].ix[-1, :]
      

      【讨论】:

        【解决方案4】:

        pandas asof 函数就是为此而生的:

        x.index.asof(start)
        

        它可以用于系列或日期时间索引。

        见:

        http://pandas.pydata.org/pandas-docs/version/0.17.0/generated/pandas.DatetimeIndex.asof.html

        【讨论】:

          猜你喜欢
          • 2017-09-02
          • 2014-09-21
          • 1970-01-01
          • 2019-07-08
          • 2021-12-15
          • 2018-06-08
          • 2022-01-03
          • 1970-01-01
          • 2013-11-18
          相关资源
          最近更新 更多