2016-03-23 71 views
3

我有一個熊貓數據幀:查找列的值的最大值出現,後組由另一列

 id    city 
[email protected] Bangalore 
[email protected]  Mumbai 
[email protected]  Jamshedpur 
[email protected]  Jamshedpur 
[email protected] Bangalore 
    [email protected]  Mumbai 
    [email protected]  Vijayawada 
    [email protected]  Vijayawada 
    [email protected]  Vijayawada 

我想找到ID明智發生的最大城市名稱。因此,對於給定的ID我可以告訴大家, - 這是他最喜歡的城市:

  id    city 
[email protected] Bangalore 
[email protected]  Vijayawada 
[email protected]  Jamshedpur 

使用GROUPBY ID和城市給人:

  id     city  count 
0 [email protected]  Bangalore 2 
1  [email protected]  Mumbai  2 
2  [email protected]  Vijayawada 3 
3 [email protected]  Jamshedpur 2 

如何繼續進行?我相信一些小組適用會做到這一點,但不知道究竟會做什麼。所以請建議。

如果某個ID有兩個或三個城市的相同計數,我可以返回任何這些城市。

+0

另一種選擇是'pd.crosstab(DF [ '城市'],DF [ '身份證'])。idxmax(軸= 0)''雖然可能crosstab'如果你有很多獨特的id和city值,就會生成一個非常大的框架。 –

+0

爲我提到的數據框,這個交叉表片段只給我[email protected]維傑亞瓦達的記錄。我認爲這是找到最大的城市總數id設置。不是明智的最大城市數。 – Satya

+0

[pandas recommended](https://github.com/pandas-dev/pandas/issues/7301)方法是'groupby('id')。apply(your_custom_function)',根據我的回答 – smci

回答

4

您可以嘗試雙重groupbysizeidxmax。輸出元組(因爲MultiIndex)的列表,所以使用apply

df = df.groupby(['id','city']).size().groupby(level=0).idxmax() 
           .apply(lambda x: x[1]).reset_index(name='city') 

另一種解決方案:

s = df.groupby(['id','city']).size() 
df = s.loc[s.groupby(level=0).idxmax()].reset_index().drop(0,axis=1) 

或者:

df = df.groupby(['id'])['city'].apply(lambda x: x.value_counts().index[0]).reset_index() 

print (df) 
        id  city 
0 [email protected] Bangalore 
1  [email protected] Vijayawada 
2 [email protected] Jamshedpur 
+0

您可以避免手動創建然後操縱MultiIndex;看到我的答案。 – smci

+0

@smci - 不確定,但'apply' +'agg'有點過於複雜;)我添加了2個其他解決方案。 – jezrael

+0

@smci - 你也不能使用head(),因爲不知道第一個組是否是max。 – jezrael

1

recommended方法是groupby('id').apply(your_custom_function),其中your_custom_function按「城市」彙總並返回最大值(或如您所述,返回多個最大值)。我們甚至不必使用.agg('city')

import pandas as pd 

def get_top_city(g): 
    return g['city'].value_counts().idxmax()  

df = pd.DataFrame.from_records(
     [('[email protected]', 'Bangalore'), ('[email protected]',  'Mumbai'), 
     ('[email protected]', 'Jamshedpur'),('[email protected]', 'Jamshedpur'), 
     ('[email protected]', 'Bangalore'), ('[email protected]',  'Mumbai'), 
     ('[email protected]',  'Vijayawada'),('0007[email protected]',  'Vijayawada'), 
     ('[email protected]',  'Vijayawada')], 
     columns=['id','city'], 
     index=None 
    ) 

topdf = df.groupby('id').apply(get_top_city) 

id 
[email protected]  Bangalore 
[email protected]  Vijayawada 
[email protected]  Jamshedpur 

# or topdf.items()/iteritems() if you want as list of (id,city) tuples 

[('[email protected]', 'Bangalore'), ('[email protected]', 'Vijayawada'), ('[email protected]', 'Jamshedpur')] 
+0

不,它沒有給出正確的結果,只需添加一條記錄,如('[email protected]。com','XYZ'),你會看到,爲什麼這不是做這件事的方法。它最終會給'[email protected]'給'xyz',而'班加羅爾'應該是答案。 – Satya

+0

它只是按ID進行分組,並且從該組中按字母順序進行比較的所有城市中返回最大值。我需要計數/發生最明智的。 – Satya

+0

固定(我以前的解決方案實際上是這樣的,我只是想盡量減少代碼) – smci

相關問題