【问题标题】:Pandas dataframe: how to find missing years in a timeseries?Pandas 数据框:如何在时间序列中找到缺失的年份?
【发布时间】:2015-07-31 02:35:42
【问题描述】:

我有一个带有时间戳索引和大约 100,000 行的 DataFrame。通过

df['year'] = df.index.year

创建一个包含每一行年份的新列很容易。现在我想找出我的时间序列中缺少哪些年份。到目前为止,我知道我可以使用 groupby 来获取“某物”,这可以让我找到唯一值。因此,

grouped = df.groupby('year')
grouped.groups.keys()

会给我数据集中存在的年份。我现在可以用

构建一个完整的年份向量
pd.date_range(df.index.min(), df.index.max(), freq='AS')

然后通过重新索引,我应该能够找到缺失的年份作为具有 NaN 值的年份。

然而,对于这样看似简单的任务来说,这听起来非常复杂,而 grouped.groups 操作实际上需要相当长的时间;大概是因为它不仅查找唯一键,而且还建立了属于每个键的行的索引列表,这是我这里不需要的功能。

有什么方法可以更直接/更有效地获取数据框列的唯一元素?

【问题讨论】:

    标签: python pandas time-series dataframe


    【解决方案1】:

    如果您想要的只是缺失年份的列表,您可以先将数据系列转换为列表,然后使用列表推导式简单地构建缺失年份的列表:

    years = df['year'].unique()
    missing_years = [y for y in range(min(years), max(years)+1) if y not in years]
    

    【讨论】:

      【解决方案2】:

      一种方法是构建一系列感兴趣的年份,然后使用isin 查看缺失值:

      In [89]:
      
      year_s = pd.Series(np.arange(1993, 2015))
      year_s
      Out[89]:
      0     1993
      1     1994
      2     1995
      3     1996
      4     1997
      5     1998
      6     1999
      7     2000
      8     2001
      9     2002
      10    2003
      11    2004
      12    2005
      13    2006
      14    2007
      15    2008
      16    2009
      17    2010
      18    2011
      19    2012
      20    2013
      21    2014
      dtype: int32
      
      In [88]:
      
      df = pd.DataFrame({'year':[1999, 2000, 2013]})
      df
      Out[88]:
         year
      0  1999
      1  2000
      2  2013
      
      In [91]:
      
      year_s[~year_s.isin(df['year'])]
      Out[91]:
      0     1993
      1     1994
      2     1995
      3     1996
      4     1997
      5     1998
      8     2001
      9     2002
      10    2003
      11    2004
      12    2005
      13    2006
      14    2007
      15    2008
      16    2009
      17    2010
      18    2011
      19    2012
      21    2014
      dtype: int32
      

      因此,在您的情况下,您可以如上所述生成年份系列,然后对于您的 df,您可以使用以下方法获取年份:

      df.index.year.unique()
      

      这将比执行groupby 快​​得多。

      注意传递给arange 的最后一个值不包含在范围内

      【讨论】:

      • 太棒了!但是,上面有一个小错误: df.index.year 返回一个 numpy 数组,而不是 pandas 系列 - 因此,它没有唯一的方法。不过,使用 pd.Series(df.index.year).unique() 可以轻松克服。
      • @maschu 是的,你可以这样做 set(df.index.year) 也可以,如果我的回答回答了你的问题,那么你可以接受它,我的左上角会有一个空的勾号回答,你也可以点赞
      • 一个后续问题:虽然这对“年”很有效,但我想对“年月”做类似的事情,即 YYYYMM 值的组合(这样每年的每个月获取特定标签),由于没有直接从索引中提取“年月”的属性,在这种情况下我该怎么办?例如,我可以定义一个 lambda 函数并将其应用于索引值吗?
      • 这个标签看起来像你建议的字符串一样吗?你应该能够做到import datetime as dt df.index.apply(lambda x: dt.datetime.strftime(x, '%Y%m')) 我认为应该可以工作
      • 找到它:f=lambda x: x.year*100 + x.month ; df.index.map(f) 可以解决问题。
      猜你喜欢
      • 2017-10-04
      • 2022-08-23
      • 2020-03-19
      • 1970-01-01
      • 2018-05-29
      • 2021-06-23
      • 1970-01-01
      • 2020-10-22
      • 2015-05-13
      相关资源
      最近更新 更多