pandas:由列層次化索引延伸的一些思考


1. 刪除列層次化索引

用pandas利用df.groupby.agg() 做聚合運算時遇到一個問題:產生了列方向上的兩級索引,且需要刪除一級索引。具體代碼如下:

# 每個uesr每天消費金額統計:和、均值、最大值、最小值、消費次數、消費種類、

action_info = student_action.groupby(['outid','date']).agg({'opfare':['sum','mean','max','min'],
                                                            'acccode':['count','unique'],}).reset_index()

action_info 表結果如下:

 刪除列的層次化索引操作如下:

# 列的層次化索引的刪除
levels = action_info.columns.levels
labels = action_info.columns.labels
print(levels,labels)
action_info.columns = levels[1][labels[1]]

2.  agg()與apply()的區別

以 student_action表為例:

apply()方法:

agg()方法:

可以看到,apply()可以展示所有維度的數據,而agg()僅可以展示一個維度的數據。

事實上,如果值是一維數組,在利用完特定的函數之后,能做到簡化的話,agg就能調用,反之,如果比如自定義的函數是排序,或者是一些些更復雜統計的函數,當然是agg所不能解決的,這時候用apply就可以解決。因為他更一般化,不存在什么簡化,什么一維數組,什么標量值。且apply會將當前分組后的數據一起傳入,可以返回多維數據。

例子:根據 student_action表,統計每個學生每天最高使用次數的終端、最低使用次數的終端以及最高使用次數終端的使用次數、最低使用次數終端的使用次數。

針對這個例子,有兩種方法:

方法一:low到爆 永不使用!! 

1. 構造每個用戶每天的終端列表,需要one-hot termid

2. 構造groupby.agg()所使用的方法

2.1 列表模糊查找,找到包含'termid_'的字段名

      termid_features = [x for i,x in enumerate(student_termid_onehot.columns.tolist()) if x.find('termid_')!=-1]

2.2 構造指定長度,指定元素的列表

      sum_methods= ['sum'for x in range(0, len(termid_features))]

2.3  agg_methods=dict(zip(termid_features,sum_methods))

3. 每個學生每天的終端使用次數明細表

    find_termid_df = student_termid_onehot.groupby(['outid','date']).agg(agg_methods).reset_index()

4. 找到student_termid_onehot中包含 'termid_'字段元素的最大值對應的字段名

4.1 構造列表保存

4.2 遍歷每行數據,構造dict,並過濾value =0.0 的 k-v

4.3 找到每個dict的value值最大的key 

      max(filtered_statics_dict, key=filtered_statics_dict.get)

方法二:優雅直觀

def transmethod(df):
    """
    每個用戶每天消費記錄最大值、最高使用次數的終端、最低使用次數的終端
    以及最高使用次數終端的使用次數、最低使用次數終端的使用次數。
    
    df type:
                  outid  opcount        date      time  oddfare  opfare  acccode  \
    3538  152211511101        5  2015-09-08  07:24:25    11290     200      210   
    6108  152211511101        6  2015-09-08  12:09:01    10440     850      210   

          termid  
    3538      13  
    6108      39  
    
    """
    # 每日最大消費額
    maxop = df['opfare'].max()
    statics_dict={}
    for i in set(df['acccode'].tolist()):
        statics_dict[i] = df['acccode'].tolist().count(i)
    highest_termid = max(statics_dict, key=statics_dict.get)
    lowhest_termid = min(statics_dict, key=statics_dict.get)
    highest_termid_freq = statics_dict[highest_termid]
    lowhest_termid_freq = statics_dict[lowhest_termid]
    
    return maxop,highest_termid,highest_termid_freq,lowhest_termid,lowhest_termid_freq

 groupby.apply() 組合使用:

pd.DataFrame(student_action.groupby(['outid','date']).apply(lambda x:transmethod(x)))

可以發現,apply()方法要比agg()方法靈活的多的多!

3. 總結

  • 列層次索引的刪除
  • 列表的模糊查找方式
  • 查找dict的value值最大的key 的方式
  • 當做簡單的聚合操作(max,min,unique等),可以使用agg(),在做復雜的聚合操作時,一定使用apply()

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM