2016-11-14 33 views
3

我有一個形狀的數據框(40,500)。數據幀中的每一行都有一些數字值,直到某個可變列號k,之後的所有條目都是nan。在熊貓數據框的行中獲取最後一個非na值

我想獲得每行最後一個非nan列的值。有沒有辦法做到這一點,而不循環遍歷數據框的所有行?

樣品數據框:

2016-06-02 7.080 7.079 7.079 7.079 7.079 7.079 nan nan nan 
2016-06-08 7.053 7.053 7.053 7.053 7.053 7.054 nan nan nan 
2016-06-09 7.061 7.061 7.060 7.060 7.060 7.060 nan nan nan 
2016-06-14 nan nan nan nan nan nan nan nan nan 
2016-06-15 7.066 7.066 7.066 7.066 nan nan nan nan nan 
2016-06-16 7.067 7.067 7.067 7.067 7.067 7.067 7.068 7.068 nan 
2016-06-21 7.053 7.053 7.052 nan nan nan nan nan nan 
2016-06-22 7.049 7.049 nan nan nan nan nan nan nan 
2016-06-28 7.058 7.058 7.059 7.059 7.059 7.059 7.059 7.059 7.059 

REQD輸出

2016-06-02 7.079 
2016-06-08 7.054 
2016-06-09 7.060 
2016-06-14 nan 
2016-06-15 7.066 
2016-06-16 7.068 
2016-06-21 7.052 
2016-06-22 7.049 
2016-06-28 7.059 

回答

7

您需要last_valid_index使用自定義功能,因爲如果所有值均爲NaN它返回KeyError

def f(x): 
    if x.last_valid_index() is None: 
     return np.nan 
    else: 
     return x[x.last_valid_index()] 

df['status'] = df.apply(f, axis=1) 
print (df) 
       1  2  3  4  5  6  7  8  9 \ 
0                   
2016-06-02 7.080 7.079 7.079 7.079 7.079 7.079 NaN NaN NaN 
2016-06-08 7.053 7.053 7.053 7.053 7.053 7.054 NaN NaN NaN 
2016-06-09 7.061 7.061 7.060 7.060 7.060 7.060 NaN NaN NaN 
2016-06-14 NaN NaN NaN NaN NaN NaN NaN NaN NaN 
2016-06-15 7.066 7.066 7.066 7.066 NaN NaN NaN NaN NaN 
2016-06-16 7.067 7.067 7.067 7.067 7.067 7.067 7.068 7.068 NaN 
2016-06-21 7.053 7.053 7.052 NaN NaN NaN NaN NaN NaN 
2016-06-22 7.049 7.049 NaN NaN NaN NaN NaN NaN NaN 
2016-06-28 7.058 7.058 7.059 7.059 7.059 7.059 7.059 7.059 7.059 

      status 
0     
2016-06-02 7.079 
2016-06-08 7.054 
2016-06-09 7.060 
2016-06-14  NaN 
2016-06-15 7.066 
2016-06-16 7.068 
2016-06-21 7.052 
2016-06-22 7.049 
2016-06-28 7.059 

替代的解決方案 - fillna方法ffill和選擇最後一列通過iloc

df['status'] = df.ffill(axis=1).iloc[:, -1] 
print (df) 
      status 
0     
2016-06-02 7.079 
2016-06-08 7.054 
2016-06-09 7.060 
2016-06-14  NaN 
2016-06-15 7.066 
2016-06-16 7.068 
2016-06-21 7.052 
2016-06-22 7.049 
2016-06-28 7.059 
4

使用agg('last')

df.groupby(['status'] * df.shape[1], 1).agg('last') 

enter image description here


'最後' AGG內產生組內的最後的有效值。我通過了一個等於列數的長度列表。此列表的每個值都是'狀態'。這意味着我正在分組。其結果是與名爲「狀態」

+1

謝謝,這解決了這個問題,但我只能接受一個答案。鑑於以色列方法的理解性和直接性,我接受他並讚揚你和他。謝謝piRSquared! – dayum

3

這裏一列的數據幀是一個基於NumPy的解決方案 -

In [113]: a 
Out[113]: 
array([[ 17., 53., nan, 63., 66., nan, nan, nan, nan, nan], 
     [ 54., 96., 71., 20., 70., 58., 91., nan, nan, nan], 
     [ 58., 26., 72., 93., 58., 29., 44., 28., 36., 88.], 
     [ nan, nan, nan, nan, nan, nan, nan, nan, nan, nan], 
     [ 94., 23., nan, nan, 92., 81., 40., 30., 84., nan]]) 

In [114]: m = ~np.isnan(a) 

In [115]: a[np.arange(m.shape[0]), m.shape[1]-m[:,::-1].argmax(1)-1] 
Out[115]: array([ 66., 91., 88., nan, 84.]) 

要口這爲數據幀,首先,我們可以提取值的數組:a = df.values,最終使輸出數據幀:

vals = a[np.arange(m.shape[0]), m.shape[1]-m[:,::-1].argmax(1)-1] 
df_out = pd.DataFrame(vals,index=df.index) 
+0

謝謝,這完美地解決了這個問題,但我只能接受一個答案。鑑於以色列方法的理解性和直接性,我接受他並讚揚你和他。謝謝Divakar! – dayum

相關問題