在存在NA

时间:2016-03-20 19:26:08

标签: python python-3.x pandas

我需要获取最小n项的DataFrame的索引,忽略NA。如果我没有NAs,我就这样做:

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 个答案:

答案 0 :(得分: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

答案 1 :(得分: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