1. 程式人生 > >Dataframe求眾數的解決方法

Dataframe求眾數的解決方法

Pandas在實際使用過程中,遇到如下問題。

有如下一個Dataframe,打算對A的每一個類別求B的眾數,但是不能使用Dataframe.groupby('A').mode(),報如下錯誤。

>>import pandas as pd
>>df = pd.DataFrame({'A':['a','a','a','a','b','b','b','b','b'],'B':[1,1,2,3,1,2,2,3,3]})
Traceback (most recent call last):

  File "<ipython-input-293-3972c0972961>", line 1, in <module>
    df.groupby('A').mode()

  File "d:\Anaconda3\lib\site-packages\pandas\core\groupby\groupby.py", line 762, in __getattr__
    return self._make_wrapper(attr)

  File "d:\Anaconda3\lib\site-packages\pandas\core\groupby\groupby.py", line 799, in _make_wrapper
    raise AttributeError(msg)

AttributeError: Cannot access callable attribute 'mode' of 'DataFrameGroupBy' objects, try using the 'apply' method

首先,定義如下統計函式。

#統計資料
def getlistnum(li):
    li = list(li)
    set1 = set(li)
    dict1 = {}
    for item in set1:
        dict1.update({item:li.count(item)})
    return dict1

檢視df統計,

>>df.groupby('A')['B'].apply(getlistnum)
A   
a  1    2
   2    1
   3    1
b  1    1
   2    2
   3    2
Name: B, dtype: int64

考慮groupby()方法可以通過agg呼叫外部函式,因此嘗試了以下方法:

法1.使用scipy.stats.mode():df中的B類別有兩個眾數,返回了B類別的眾數取了較小的結果

>>from scipy import stats
>>df.groupby('A').agg(lambda x: stats.mode(x)[0][0]).reset_index()
   A  B
0  a  1
1  b  2

法2.使用value_counts() ,有兩個眾數以上的時候,返回了B類別的眾數取了較大的結果

>>df.groupby('A').agg(lambda x: x.value_counts().index[0]).reset_index()
   A  B
0  a  1
1  b  3

法3.使用pd.Series.mode():該函式是返回Series的眾數的,當眾數有多個時,會返回一個list,裡面包含了所有眾數

>>df.groupby('A').agg(pd.Series.mode).reset_index()
   A       B
0  a       1
1  b  [2, 3]