如何从pandas DataFrame中有效地选择行?

时间:2014-07-22 08:57:48

标签: python pandas

下表包含一些键和值:

N = 100
tbl = pd.DataFrame({'key':np.random.randint(0, 10, N), 
    'y':np.random.rand(N), 'z':np.random.rand(N)})

我想获得一个DataFrame,其中每行包含一个键以及与指定字段的最小值对应的所有字段。

由于原始表非常大,我对最有效的方式感兴趣。

注意获取字段的最小值很简单:

tbl.groupby('key').agg(pd.Series.min)

但是这会独立地获取每个字段的最小值,我想知道y的最小值是什么,z值对应于什么{{1}}。

下面我以天真的方式回答我的问题,但我怀疑有更好的方法

2 个答案:

答案 0 :(得分:1)

这是一种直截了当的方法:

gr = tbl.groupby('key')
def take_min_y(t):
    ix = t.y.argmin()
    return t.loc[[ix]]

tbl_mins = gr.apply(take_min_y)

有更好的方法吗?

答案 1 :(得分:1)

根据您的更新编辑,我相信以下是您想要的:

In [107]:

tbl.iloc[gr['y'].agg(pd.Series.idxmin)]
Out[107]:
    key         y         z
47    0  0.094841  0.221435
26    1  0.062200  0.748082
45    2  0.032497  0.160199
28    3  0.002242  0.064829
73    4  0.122438  0.723844
75    5  0.128193  0.638933
79    6  0.071833  0.952624
86    7  0.058974  0.113317
36    8  0.068757  0.611111
12    9  0.082604  0.271268

idxmin返回最小值的索引,然后我们可以使用它来过滤原始数据帧以选择这些行。

计时显示这种方法快了大约7倍:

In [108]:

%timeit tbl.iloc[gr['y'].agg(pd.Series.idxmin)]
def take_min_y(t):
    ix = t.y.argmin()
    return t.loc[[ix]]

%timeit tbl_mins = gr.apply(take_min_y)
1000 loops, best of 3: 1.08 ms per loop
100 loops, best of 3: 7.06 ms per loop