下表包含一些键和值:
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}}。
下面我以天真的方式回答我的问题,但我怀疑有更好的方法
答案 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