2016-07-23 68 views
3

我被困在如何获取唯一标识符的DataFrame的最新非NaN值。所以我有一个熊猫数据框与身份证,价值,和多年列,与此类似:获取熊猫标识符中每个标识符的最新非NaN值

| ID | Values | Year 
------------------------- 
0 | A | 4.0 | 2016 
1 | B | NaN | 2016 
2 | C | NaN | 2016 
3 | D | 1.0 | 2016 
4 | A | 2.0 | 2015 
5 | B | 2.0 | 2015 
6 | C | 1.0 | 2015 
7 | D | 3.0 | 2015 
8 | A | 2.0 | 2014 
9 | B | 2.0 | 2014 
10| C | 3.0 | 2014 
11| D | NaN | 2014 

我试图找出如何获得最新(最近)的列表非-NAN每个ID的值。因此,名单对于这种情况应该是:

[4.0, 2.0, 1.0, 1.0] 

分别是A,B,C,和d的最新值(跳过任意NaN的)。 到目前为止,我做这样一个支点走近这个:

df.pivot(index = 'Year', columns = 'ID', values = 'Values') 

所以,我得到:

ID | A | B | C | D 
---------------------- 
Year | | | | 
2014 |2.0|2.0|3.0|NaN 
2015 |2.0|2.0|1.0|3.0 
2016 |4.0|NaN|Nan|1.0 

在这里,我stuck-这将是得到的最好方式每个ID最近的非NaN值?任何建议使用原来的DataFrame或pivoted的将不胜感激!

回答

3

另一个groupby选项:

如果数据是由'Year'下降,在该示例数据已经排序,如:

df.groupby('ID')['Values'].first() 

如果数据尚未排序:

df.sort_values(by='Year').groupby('ID')['Values'].last() 

所得输出:

ID 
A 4.0 
B 2.0 
C 1.0 
D 1.0 
+0

我忘了排序。很好完成 – piRSquared

+0

@piRSquared:我没有注意到它已经在示例数据中排序了。如果这是预期的格式,则不需要排序。 – root

3

你真是太亲近了。使用ffill()

df.pivot(index='Year',columns='ID',values='Values').ffill().values[-1] 

结果:

array([ 4., 2., 1., 1.]) 
1

这应做到:

df.ix[df.groupby('ID').Values.apply(lambda x: x.first_valid_index())] 

enter image description here