如果滞后和超前相同,则替换缺失值

Replacing missing values if lag and lead are the same

我有年度数据。这些年份中的每一年都存储在一个单独的数据框中。 一些信息在某些年份缺失,但在其他年份可能可用。只有在失踪年份前后观察到的信息,我才能相信。 例如:

Index     Identifier      Date      Owner
 1           A             2005       F
 2           A             2006       NaN
 3           A             2007       F
 4           B             2005       G
 5           B             2006       NaN
 6           B             2007       NaN
 7           B             2008       G
 8           B             2009       NaN
 9           B             2010       F
 10          C             2006       H
 11          C             2007       NaN
 12          C             2008       NaN

这最终应该是这样的:

 Index     Identifier      Date      Owner
 1           A             2005       F
 2           A             2006       F
 3           A             2007       F
 4           B             2005       G
 5           B             2006       G
 6           B             2007       G
 7           B             2008       G
 8           B             2009       NaN
 9           B             2010       F
 10          C             2006       H
 11          C             2007       NaN
 12          C             2008       NaN

所以只有当我观察到缺失年份前后相同时,才会有变化。如果之后我没有观察到任何东西,或者如果我观察到一些不同的东西,我就不应该进行更改。 真实数据是每年大约 1000 万次观察。所以一个循环将是非常低效的。

我目前的解决方案是:

framestot=(df2005, df2006, df2007, df2008, df2009, df2010)
df=pd.concat(framestot, ignore_index=True)
df=df.sort(columns='date', ascending=True, kind='quicksort')
df['lag'] = df.Owner 
df['lead'] = df.Owner
df['lag'] = df.groupby(['Identifier'])['lag'].transform(lambda grp: grp.fillna(method='ffill'))      
df['lead'] = df.groupby(['Identifier'])['lead'].transform(lambda grp: grp.fillna(method='bfill'))
df.loc[df['Owner'].isnull() & df['lead'] == df['lag'],'Owner'] = df.lag

这似乎是一种非常低效的解决方法。有没有办法直接调用这些信息? 如果我没记错的话,这也需要第一个未丢失的滞后和领先。我可以限制这个吗?例如,如果我只想在过去两年和未来两年内相同时更换。如果数据来自两年多以前,我会保留缺失值。

一个简单但不是特别有效的解决方案是比较正向填充和反向填充:

In [11]: df['Owner'].ffill()
Out[11]:
0     F
1     F
2     F
3     G
4     G
5     G
6     G
7     G
8     F
9     H
10    H
11    H
Name: Owner, dtype: object

In [12]: ff = df['Owner'].ffill()

In [13]: ff[ff == df['Owner'].bfill()]
Out[13]:
0    F
1    F
2    F
3    G
4    G
5    G
6    G
8    F
9    H
Name: Owner, dtype: object

并将这些拼接回原始列:

In [14]: df['Owner'] = ff[ff == df['Owner'].bfill()]

In [15]: df
Out[15]:
    Index Identifier  Date Owner
0       1          A  2005     F
1       2          A  2006     F
2       3          A  2007     F
3       4          B  2005     G
4       5          B  2006     G
5       6          B  2007     G
6       7          B  2008     G
7       8          B  2009   NaN
8       9          B  2010     F
9      10          C  2006     H
10     11          C  2007   NaN
11     12          C  2008   NaN