2016-03-20 67 views
1

我需要獲取最小n項目的DataFrame的索引,而忽略NA。如果我沒有來港,我應該這樣做:在存在NA時獲取最小項目的索引

s = pd.Series([4,3,1,5,2], index=range(10,15)) 
idx = s.argsort()[:2] 
# check: 
s.iloc[idx] # [1, 2] as desired 

但在NA的存在,這是不行的:

s = pd.Series([None,3,1,5,2], index=range(10,15)) 
idx = s.argsort()[:2] 
# check: 
s.iloc[idx] # [2.0, 3.0] instead of [1.0, 2.0] 

這是因爲arg_sort(不像sort_values)簡單地完全跳過NA,並且不包括它們在計數中。有沒有像arg_sort那樣的功能,但將NA放在最後?或者,重寫上述代碼與NA一起工作的最佳方法是什麼?

我想我可以在每次執行此操作之前都會執行drop_na(),但是這將在數據框中爲多個列完成,因此對每個列再次傳遞似乎效率低下。

回答

2

IIUC,您可以使用nsmallest,獲得對應最小值的所需量指數:

In [2]: s = pd.Series([4,3,1,5,2], index=range(10,15)) 

In [3]: a = s.nsmallest(2) 

In [4]: a 
Out[4]: 
12 1 
14 2 
dtype: int64 

In [5]: s = pd.Series([None,3,1,5,2], index=range(10,15)) 

In [6]: a = s.nsmallest(2) 

In [7]: a 
Out[7]: 
12 1.0 
14 2.0 
dtype: float64 
+0

啊。 ..我忘了' nsmallest'也保持索引。 – max

2

IIUC你可以使用sort_values

s = pd.Series([None,3,1,5,2], index=range(10,15)) 

In [140]: s.sort_values()[:2] 
Out[140]: 
12 1.0 
14 2.0 
dtype: float64 

對於第一種情形

s = pd.Series([4,3,1,5,2], index=range(10,15)) 

In [142]: s.sort_values()[:2] 
Out[142]: 
12 1 
14 2 
dtype: int64 

時間:

In [143]: %timeit s.sort_values()[:2] 
1000 loops, best of 3: 349 µs per loop 

In [144]: %timeit s.nsmallest(2) 
1000 loops, best of 3: 370 µs per loop 

如果需要指數爲值,您可以使用index屬性:

In [145]: s.sort_values()[:2].index 
Out[145]: Int64Index([12, 14], dtype='int64') 

編輯

對於大系列nsmallest工作速度快:

s = pd.Series(np.random.random(size=100000)) 

In [16]: %timeit s.nsmallest(2) 
100 loops, best of 3: 2.5 ms per loop 

In [17]: %timeit s.sort_values()[:2] 
100 loops, best of 3: 12.4 ms per loop 
+1

只有在大型數據集上'nsmallest'纔會快得多? – max

+0

@max你說得對。添加時間示例 –