Python 熊猫数据框架:如何在时间序列中找到缺失的年份?

Python 熊猫数据框架:如何在时间序列中找到缺失的年份?,python,pandas,time-series,dataframe,Python,Pandas,Time Series,Dataframe,我有一个带有时间戳索引和大约100000行的数据帧。通过 df['year'] = df.index.year 创建包含每行年份的新列很容易。现在我想找出我的时间序列中缺少的年份。到目前为止,我了解到我可以使用groupby获得“某些东西”,从而可以找到唯一的值。因此, grouped = df.groupby('year') grouped.groups.keys() 将给出数据集中存在的年份。我现在可以用 pd.date_range(df.index.min(), df.index.ma

我有一个带有时间戳索引和大约100000行的数据帧。通过

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值的年份一样

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


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

一种方法是构造一系列感兴趣的年份,然后使用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的最后一个值不包括在范围内

如果您只需要缺失年份的列表,您可以首先将数据系列转换为列表,然后使用列表创建缺失年份的列表:

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

明亮的但是,上面有一个小小的错误:df.index.year返回一个numpy数组,而不是pandas系列-因此,它没有唯一的方法。使用pd.Series(df.index.year).unique()很容易克服。@maschu是的,这是真的,你可以只做
set(df.index.year)
也可以,如果我的答案回答了你的问题,那么你可以接受,我的答案左上角会有一个空的勾号,你也可以向上问一个后续问题:虽然这对你来说很有用“year”,我想对“yearmonth”做类似的事情,即YYYYMM值的组合(这样每年的每个月都有一个特定的标签),因为没有直接提取“yearmonth”的属性“从索引中,在这种情况下我可以做什么?例如,我可以定义一个lambda函数并将其应用于索引值吗?这个标签将如何看起来像您所建议的字符串?您应该能够
将datetime导入为dt df.index.apply(lambda x:dt.datetime.strftime(x,'%Y%m'))
我认为应该找到它:f=lambda x:x.year*100+x.month;map(f)实现了这一点。