【问题标题】:Slicing based on dates Pandas Dataframe基于日期的切片 Pandas Dataframe
【发布时间】:2015-07-19 22:15:41
【问题描述】:

我有一个包含日期、商店编号、售出单位和降雨总量的大型数据框。好像是这样的……

  date        store_nbr      units            preciptotal
  2014-10-11       1          0                0.00
  2014-10-12       1          0                0.01
  2014-10-13       1          2                0.00
  2014-10-14       1          1                2.13
  2014-10-15       1          0                0.00
  2014-10-16       1          0                0.87
  2014-10-17       1          3                0.01
  2014-10-18       1          0                0.40

我想在总降水量大于 1 的任何日期周围选择一个三天窗口。对于这个小例子,我想取回前 7 行,2014-10-14 之前的 3 天,之后的三天2014-10-142014-10-14 因为它的总分大于 1。

【问题讨论】:

    标签: python date pandas


    【解决方案1】:

    对于特定值,您可以这样做:

    In [84]:
    
    idx = df[df['preciptotal'] > 1].index[0]
    df.iloc[idx-3: idx+4]
    Out[84]:
            date  store_nbr  units  preciptotal
    0 2014-10-11          1      0         0.00
    1 2014-10-12          1      0         0.01
    2 2014-10-13          1      2         0.00
    3 2014-10-14          1      1         2.13
    4 2014-10-15          1      0         0.00
    5 2014-10-16          1      0         0.87
    6 2014-10-17          1      3         0.01
    

    对于更一般的情况,您可以获得满足条件的索引数组

    idx_vals = df[df['preciptotal'] > 1].index
    

    然后您可以生成切片或遍历数组值:

    for idx in idx_values:
        df.iloc[idx-3: idx+4]
    

    这假设您的索引是基于 0 的 int64 索引,您的样本是

    【讨论】:

      【解决方案2】:

      这里有两种方法可以在不循环索引值的情况下构建选择掩码:

      你可以找到preciptotal大于1的行:

      mask = (df['preciptotal'] > 1)
      

      然后使用scipy.ndimage.binary_dilation 将掩码扩展到 7 天窗口:

      import scipy.ndimage as ndimage
      import pandas as pd
      
      df = df = pd.read_table('data', sep='\s+')
      
      mask = (df['preciptotal'] > 1)
      mask = ndimage.binary_dilation(mask, iterations=3)
      
      df.loc[mask]
      

      产量

               date  store_nbr  units  preciptotal
      0  2014-10-11          1      0         0.00
      1  2014-10-12          1      0         0.01
      2  2014-10-13          1      2         0.00
      3  2014-10-14          1      1         2.13
      4  2014-10-15          1      0         0.00
      5  2014-10-16          1      0         0.87
      6  2014-10-17          1      3         0.01
      

      或者,使用 NumPy(但没有 scipy 依赖项),您可以使用 mask.shiftnp.logical_and.reduce

      mask = (df['preciptotal'] > 1)
      mask = ~np.logical_and.reduce([(~mask).shift(i) for i in range(-3, 4)]).astype(bool)
      # array([ True,  True,  True,  True,  True,  True,  True, False], dtype=bool)
      

      【讨论】:

      • 这是一个比我的+1更有趣的答案
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-17
      • 2016-08-05
      • 1970-01-01
      • 2017-03-28
      • 1970-01-01
      相关资源
      最近更新 更多