【问题标题】:Find gaps in pandas time series dataframe sampled at 1 minute intervals and fill the gaps with new rows查找以 1 分钟间隔采样的 pandas 时间序列数据帧中的空白,并用新行填充空白
【发布时间】:2019-07-02 16:52:21
【问题描述】:

问题

我有一个数据框,其中包含每隔 1 分钟采样的财务数据。有时可能会丢失一两行数据。

  • 我正在寻找一种好的(简单而有效的)方法来将新行插入到数据框中的缺失数据点。
  • 除了包含时间戳的索引之外,新行可以为空。

例如:

 #Example Input---------------------------------------------
                      open     high     low      close
 2019-02-07 16:01:00  124.624  124.627  124.647  124.617  
 2019-02-07 16:04:00  124.646  124.655  124.664  124.645  

 # Desired Ouput--------------------------------------------
                      open     high     low      close
 2019-02-07 16:01:00  124.624  124.627  124.647  124.617  
 2019-02-07 16:02:00  NaN      NaN      NaN      NaN
 2019-02-07 16:03:00  NaN      NaN      NaN      NaN
 2019-02-07 16:04:00  124.646  124.655  124.664  124.645 

我目前的方法是基于这篇文章 - Find missing minute data in time series data using pandas - 仅建议如何识别差距。不是如何填充它们。

我正在做的是创建一个间隔为 1 分钟的 DateTimeIndex。然后使用这个索引,我创建了一个全新的数据帧,然后可以将其合并到我的原始数据帧中,从而填补空白。代码如下所示。这似乎是一个关于这样做的方式。 我想知道是否有更好的方法。也许重新采样数据?

import pandas as pd
from datetime import datetime

# Initialise prices dataframe with missing data
prices = pd.DataFrame([[datetime(2019,2,7,16,0),  124.634,  124.624, 124.65,   124.62],[datetime(2019,2,7,16,4), 124.624,  124.627,  124.647,  124.617]])
prices.columns = ['datetime','open','high','low','close']
prices = prices.set_index('datetime')
print(prices)

# Create a new dataframe with complete set of time intervals
idx_ref = pd.DatetimeIndex(start=datetime(2019,2,7,16,0), end=datetime(2019,2,7,16,4),freq='min')
df = pd.DataFrame(index=idx_ref)

# Merge the two dataframes 
prices = pd.merge(df, prices, how='outer', left_index=True, 
right_index=True)
print(prices)

【问题讨论】:

    标签: python python-3.x pandas


    【解决方案1】:

    使用DataFrame.asfreq 与Datetimeindex 一起使用:

    prices = prices.set_index('datetime').asfreq('1Min')
    print(prices)
                            open     high      low    close
    datetime                                               
    2019-02-07 16:00:00  124.634  124.624  124.650  124.620
    2019-02-07 16:01:00      NaN      NaN      NaN      NaN
    2019-02-07 16:02:00      NaN      NaN      NaN      NaN
    2019-02-07 16:03:00      NaN      NaN      NaN      NaN
    2019-02-07 16:04:00  124.624  124.627  124.647  124.617
    

    【讨论】:

      【解决方案2】:

      @jezrael 的proposal 最初对我不起作用,因为我的index 曾经与DatetimeIndex 的类型不同。 prices.asfreq() 的执行清除了所有 prices 数据,尽管它以这种方式用 Nan 填补了空白:

                               open     high      low    close
      datetime                                               
      2019-02-07 16:00:00      NaN      NaN      NaN      NaN
      2019-02-07 16:01:00      NaN      NaN      NaN      NaN
      2019-02-07 16:02:00      NaN      NaN      NaN      NaN
      2019-02-07 16:03:00      NaN      NaN      NaN      NaN
      2019-02-07 16:04:00      NaN      NaN      NaN      NaN
      

      要解决这个问题,我必须像这样更改index 列的类型

      prices['date'] = pd.to_datetime(prices['datetime'])
      prices = prices.set_index('date')
      prices.drop(['datetime'], axis=1, inplace=True)
      

      该代码会将'datetime'列的类型转换为DatetimeIndex类型,并将新列设置为index

      现在我可以打电话了

      prices = prices.asfreq('1Min')
      

      【讨论】:

        【解决方案3】:

        更手动的答案是:

        from datetime import datetime, timedelta
        from dateutil import parser
        
        import pandas as pd
        
        
        
        df = pd.DataFrame({
         'a': ['2021-02-07 11:00:30', '2021-02-07 11:00:31', '2021-02-07 11:00:35'],
         'b': [64.8, 64.8, 50.3]
        })
        
        max_dt = parser.parse(max(df['a']))
        min_dt = parser.parse(min(df['a']))
        
        
        dt_range = []
        while min_dt <= max_dt:
          dt_range.append(min_dt.strftime("%Y-%m-%d %H:%M:%S"))
          min_dt += timedelta(seconds=1)
        
        
        complete_df = pd.DataFrame({'a': dt_range})
        final_df = complete_df.merge(df, how='left', on='a')
        

        它转换以下数据帧:

                             a     b
        0  2021-02-07 11:00:30  64.8
        1  2021-02-07 11:00:31  64.8
        2  2021-02-07 11:00:35  50.3
        

        到:

                             a     b
        0  2021-02-07 11:00:30  64.8
        1  2021-02-07 11:00:31  64.8
        2  2021-02-07 11:00:32   NaN
        3  2021-02-07 11:00:33   NaN
        4  2021-02-07 11:00:34   NaN
        5  2021-02-07 11:00:35  50.3
        

        我们可以稍后填充它的空值

        【讨论】:

          猜你喜欢
          • 2021-11-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-09
          • 1970-01-01
          • 2017-11-27
          • 1970-01-01
          • 2014-09-09
          相关资源
          最近更新 更多