2013-10-29 41 views
4

假設我有一個熊貓數據幀是這樣的:如何使用argmin與GROUPBY在大熊貓

cat val 
0 a 1 
1 a 6 
2 a 12 
3 b 2 
4 b 5 
5 b 11 
6 c 4 
7 c 22 

而且我想知道,每個類別(的「貓」的每個值)是什麼位置的值最接近給定值,比如5.5。我可以減去我的目標值,並取絕對值,給我這樣的東西:

cat val val_delt 
0 a 1  4.5 
1 a 6  0.5 
2 a 12  6.5 
3 b 2  3.5 
4 b 5  0.5 
5 b 11  5.5 
6 c 4  1.5 
7 c 22  16.5 

但我被困在下一步去哪裏。我首先想到的是使用與GROUPBY()argmin(),但是這給出了一個錯誤:在這裏我遍歷的所有值

In [375]: df.groupby('cat').val_delt.argmin() 
--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython-input-375-a2c3dbc43c50> in <module>() 
----> 1 df.groupby('cat').val_delt.argmin() 

TypeError: 'Series' object is not callable 

我當然可以,拿出在標準Python一些可怕的哈克事cat,然後選擇與該值對應的數據子集,然後執行argmin操作,然後找出原始數據幀中該行所在的位置。但是要做到這一點,必須有一種更優雅的方式。

我想要什麼作爲輸出或者是這樣的:

cat val 
1 a 6  
4 b 5  
6 c 4 

或至少一些結構,其中包含相關信息(例如 - { 'A':1, 'B':4' c':6})。我不在乎是否回到指數值或指數位置,但我需要兩者中的一個。我不在乎收回價值 - 一旦我擁有了索引子集,我總能得到它。

+0

這個問題很有用,它有很多用例。謝謝! – Aaron

回答

5

argmin()不是AGG功能,您可以使用應用來獲得各組最接近的索引:

txt = """ cat val 
0 a 1 
1 a 6 
2 a 12 
3 b 2 
4 b 5 
5 b 11 
6 c 4 
7 c 22""" 

import io 

df = pd.read_csv(io.BytesIO(txt), delim_whitespace=True, index_col=0) 
df["val_delt"] = (df.val - 5.5).abs() 
idx = df.groupby("cat").apply(lambda df:df.val_delt.argmin()) 
df.ix[idx, :] 

輸出:

cat val val_delt 
1 a 6  0.5 
4 b 5  0.5 
6 c 4  1.5 
3

只是增加HYRY的回答,您可以使用idxmin 。 例如:

import io 
txt = """ cat val 
0 a 1 
1 a 6 
2 a 12 
3 b 2 
4 b 5 
5 b 11 
6 c 4 
7 c 22""" 
df = pd.read_csv(io.BytesIO(txt.encode()), delim_whitespace=True, index_col=0) 
df["val_delt"] = (df.val - 5.5).abs() 
idx = df.groupby("cat").apply(lambda df:df.val_delt.idxmin()) 
df.ix[idx, :]