1. 程式人生 > >python3中的groupby函式用法

python3中的groupby函式用法

原文地址:http://www.cnblogs.com/zhangzhangwhu/p/7219651.html

前言

Python的pandas包提供的資料聚合與分組運算功能很強大,也很靈活。《Python for Data Analysis》這本書第9章詳細的介紹了這方面的用法,但是有些細節不常用就容易忘記,遂打算把書中這部分內容總結在部落格裡,以便複習檢視。根據書中的章節,這部分知識包括以下四部分:

1.GroupBy Mechanics(groupby技術)

2.Data Aggregation(資料聚合)

3.Group-wise Operation and Transformation(分組級運算和轉換)

4.Pivot Tables and Cross-Tabulation(透視表和交叉表)

本文是第一部分,介紹groupby技術。

一、分組原理

核心:

1.不論分組鍵是陣列、列表、字典、Series、函式,只要其與待分組變數的軸長度一致都可以傳入groupby進行分組。

2.預設axis=0按行分組,可指定axis=1對列分組。

對資料進行分組操作的過程可以概括為:split-apply-combine三步:

1.按照鍵值(key)或者分組變數將資料分組。

2.對於每組應用我們的函式,這一步非常靈活,可以是python自帶函式,可以是我們自己編寫的函式。

3.將函式計算後的結果聚合。

figure1

圖1:分組聚合原理(圖片來自《Python for Data Analysis》page 252)

複製程式碼
import pandas as pd
import numpy as np

df = pd.DataFrame({'key1' : ['a', 'a', 'b', 'b', 'a'],
    'key2' : ['one', 'two', 'one', 'two', 'one'],
    'data1' : np.random.randn(5),
    'data2' : np.random.randn(5)})
複製程式碼

figure2

我們將key1當做我們的分組鍵值,對data1進行分組,再求每組的均值:

grouped = df['data1'].groupby(df['key1'])

語法很簡單,但是這裡需要注意grouped的資料型別,它不在是一個數據框,而是一個GroupBy物件。

grouped

figure3

實際上,在這一步,我們並沒有進行任何計算僅僅是建立用key1分組後建立了一個GroupBy物件,我們後面函式的任何操作都是基於這個物件的。

求均值:

grouped.mean()

figure4

剛剛我們只是用了key1進行了分組,我們也可以使用兩個分組變數,並且通過unstack方法進行結果重塑:

means = df['data1'].groupby([df['key1'], df['key2']]).mean()
means

figure5

means.unstack

figure6

以上我們的分組變數都是df內部的Series,實際上只要是和key1等長的陣列也可以:

states = np.array(['Ohio', 'California', 'California', 'Ohio', 'Ohio'])
years = np.array([2005, 2005, 2006, 2005, 2006])
df['data1'].groupby([states, years]).mean()

figure6

二、對分組進行迭代

GroupBy物件支援迭代操作,會產生一個由分組變數名和資料塊組成的二元元組:

for name, group in df.groupby('key1'):
    print name
    print group

figure7

如果分組變數有兩個:

for (k1,k2), group in df.groupby(['key1','key2']):
    print k1,k2
    print group

figure8

我們可以將上面的結果轉化為list或者dict,來看看結果是什麼樣的:

list(df.groupby(['key1','key2']))

figure9

看不太清楚,我們來看看這個列表的第一個元素:

list(df.groupby(['key1','key2']))[0]

figure10

同樣,我們也可以將結果轉化為dict(字典):

dict(list(df.groupby(['key1','key2'])))

figure11

dict(list(df.groupby(['key1','key2'])))[('a','one')]

figure12

以上都是基於行進行分組,因為預設情況下groupby是在axis=0方向(行方向)進行分組,我們可以指定axis=1方向(列方向)進行分組:

grouped=df.groupby(df.dtypes,axis=1)
list(grouped)[0]

figure13

dict(list(grouped))

figure14

注意,

'''下面兩段語句功能一樣'''
df.groupby('key1')['data1']
df.data1.groupby(df.key1)

三、通過字典進行分組

people = pd.DataFrame(np.random.randn(5, 5),
     columns=['a', 'b', 'c', 'd', 'e'],
     index=['Joe', 'Steve', 'Wes', 'Jim', 'Travis'])
people.ix[2:3, ['b', 'c']] = np.nan # 新增缺失值
people

figure15

假如,我們想按列進行聚合,該怎麼操作呢?

我們根據實際情況,對列名建立字典,然後將此字典傳入groupby,切記指定axis=1,因為我們是對列進行分組聚合:

mapping = {'a': 'red', 'b': 'red', 'c': 'blue',
     'd': 'blue', 'e': 'red', 'f' : 'orange'}
by_columns=people.groupby(mapping,axis=1)
by_columns.mean()

figure16

既然我們可以通過傳入字典來對列進行分組,那麼肯定也可以通過傳入Series來對列進行分組了(Series中的index就相當字典中的key嘛):

map_series = pd.Series(mapping)
people.groupby(map_series,axis=1).count()

figure17

四、通過函式進行分組

剛剛我們分組時利用了dict和series建立對映,對於一些複雜的需求,我們可以直接對groupby函式傳遞函式名來進行分組,以剛才的people資料為例,如果我們想按行分組,分組的key是每個人名的字母長度,該怎麼做呢?比較直接的想法是相對每個名字求長度,建立一個數組,然後將這個陣列傳入groupby,我們來試驗一下:

l=[len(x) for x in people.index]
people.groupby(l).count()

figure18

方案可行,那麼有沒有更快捷更優美的方法呢?當然有啦,我們只需將len這個函式名傳給groupby即可:

people.groupby(len).count()

figure18

除了傳遞函式,我們也可以將函式和dict,series,array一起使用,畢竟最後都會統統轉化為陣列:

key_list = ['one', 'one', 'one', 'two', 'two']
people.groupby([len, key_list]).min()

figure19

五、根據索引級別分組

剛剛我們的資料索引只有一級,當資料有多級索引時,可以通過level指定我們想要分組的索引,注意要使用axis=1表示按列:

columns = pd.MultiIndex.from_arrays([['Asian', 'Asian', 'Asian', 'America', 'America'],
    ['China','Japan','Singapore','United States','Canada']], names=['continent', 'country'])
hier_df = pd.DataFrame(np.random.randn(4, 5), columns=columns)
hier_df

figure19

我們按洲進行分組求和:

figure20

相關推薦

python3eval函式用法簡介

python中eval函式的用法十分的靈活,這裡主要介紹一下它的原理和一些使用的場合。 下面是從python的官方文件中的解釋:    The arguments are a string and optional globals and locals. If provi

python3groupby函式用法

原文地址:http://www.cnblogs.com/zhangzhangwhu/p/7219651.html 前言 Python的pandas包提供的資料聚合與分組運算功能很強大,也很靈活。《Python for Data Analysis》這本書第9章詳細的介

Python3input的用法

inpu 換行符 換行 put col you 標準輸入 eas code input()是一種獲取用戶輸入的方法,從標準輸入中讀入一個字符串,並自動忽略換行符\n。 換行符\n >>> print(‘a\nb‘)ab >>> user

numpyflatten()函式用法

flatten是numpy.ndarray.flatten的一個函式,其官方文件是這樣描述的: ndarray.flatten(order='C') Return a copy of the array collapsed into one dimension. Parameters:

Pythonsplit()函式用法和例項

一、描述 split()通過指定分隔符對字串進行切片,如果引數num 有指定值,則僅分隔 num 個子字串 函式形式:str.split(str="", num=string.count(str)) 引數: str -- 分隔符,預設為所有的空字元,包括空格、換行(\n)、製表

C++sort函式用法

C++中sort函式用法 排序示例: 輸入兩個數n,t,其中n是待排的結構體個數,t=0代表用降序排序,t = 1表示用升序排序 例如這樣: 例示: jack 70 peter 96 Tom 70 smith 67 從高到低 成績 peter 96 jack 70

【轉】Python關鍵語法-閉包:函式函式用法例項

本文例項講述了Python閉包的用法。分享給大家供大家參考,具體如下: Python函式中也可以定義函式,也就是閉包。跟js中的閉包概念其實差不多,舉個Python中閉包的例子。 def make_adder(addend): def adder(augend

**matlab eig 函式用法**

1、eig函式: 特徵值和特徵向量。 2、用法說明: (1)e = eig(A) 返回一個列向量,其中包含方陣 A 的特徵值。 (2)[V,D] = eig(A) 返回特徵值的對角矩陣 D 和矩陣 V,其列是對應的右特徵向量, 使得 AV = VD。 (3)[

**matlabany()函式用法**

1、any(A): 確定任何陣列元素是否為非零。 2、用法說明: (1)B = any(A) 如果 A 為向量,當 A 的任何元素是非零數字或邏輯 1 (true) 時,B = any(A) 返回邏輯 1,當所有元素都為零時,返回邏輯 0 (false) 。 如果 A 為

**matlabisnan()函式用法**

1、isnan(A): 判斷陣列的元素是否是NaN。(True for Not-a-Number.) 2、用法說明: B = isnan(A) 返回一個與A相同維數的陣列; 若A的元素為NaN(非數值),在對應位置上返回邏輯1(真),否則返回邏輯0(假)。 3、例子 (InF

【轉載】oracledecode函式用法

1、DECODE的語法:DECODE(value,if1,then1,if2,then2,if3,then3,...,else)。表示假設value 等於if1時,DECODE函式的結果返回then1,...,假設不等於不論什麼一個if值。則返回else 2、該函式的含義例如以下:  IF 條件=值1 TH

Python 面向物件--Python2和Python3@abstractmethod的用法

抽象方法: 抽象方法表示基類的一個方法,沒有實現,所以基類不能例項化,子類實現了該抽象方法才能被例項化。 Python的abc提供了@abstractmethod裝飾器實現抽象方法,下面以Python3的abc模組舉例。 @abstractmethod: 見下圖的

STLlist容器sort函式用法

首先,宣告一下,由於list基礎結構是連結串列,不能直接用下標【】來直接取某一元素。 1、當list 中型別是int或者string型別時,直接呼叫sort函式,即 void ListSortTest1() {list<string> num;num.push_

sparkflatMap函式用法--spark學習(基礎)

說明 在spark中map函式和flatMap函式是兩個比較常用的函式。其中 map:對集合中每個元素進行操作。 flatMap:對集合中每個元素進行操作然後再扁平化。 理解扁平化可以舉個簡單例子 val arr=sc.parallelize(Ar

sparkflatMap函式用法

說明 在spark中map函式和flatMap函式是兩個比較常用的函式。其中 map:對集合中每個元素進行操作。 flatMap:對集合中每個元素進行操作然後再扁平化。  理解扁平化可以舉個簡單例子 val arr=sc.parallelize(Array(("A",1)

Python3map函式的問題

Python3中map函式 在Python2中map函式會返回一個list列表,如程式碼: >>> def f(x, y): return (x, y) >>> l

phpsprintf函式用法

在使用sprintf過程中,有時候會重複使用後面的引數 <?php $num = 5; $location = 'tree'; $format = 'The %2$s contains %1$d

jsmatch函式用法

javascript中的match函式是使用正則表示式對字串進行查詢,並將查詢的結果作為陣列返回,在實際開發中非常的有用,使用方法如下: stringObj.match(rgExp) 其中stringObj是必選項。對其

matlab max函式用法

Matlab中max函式在矩陣中求函式大小的例項如下:(1)C = max(A)返回一個數組各不同維中的最大元素。如果A是一個向量,max(A)返回A中的最大元素。如果A是一個矩陣,max(A)將A的每一列作為一個向量,返回一個行向量,向量的第i個元素是矩陣A的第i列上的最大值。 如果A是多維陣列,max(

Learning Python 018 Python2 和 Python3 range()函式的使用

使用的電腦系統:Windows 10 64位 使用的開發整合環境:PyCharm 2016.1.4 使用的Python的版本:python 2.7.10 和 python 3.5.0 ra