1. 程式人生 > 其它 >Elasticsearch 論壇實戰-使用copy_to定製組合field解決cross-fields搜尋弊端

Elasticsearch 論壇實戰-使用copy_to定製組合field解決cross-fields搜尋弊端

技術標籤:DW-pandas

第四章 分組

分組依據的本質
在groupby中傳入相應列名構成的列表即可。例如,現想根據學校和性別進行分組,統計身高的均值就可以如下寫出:

df.groupby(['School', 'Gender'])['Height'].mean()

在這裡插入圖片描述
groupby的分組依據都是直接可以從列中按照名字獲取的,那如果想要通過一定的複雜邏輯來分組,例如根據學生體重是否超過總體均值來分組,同樣還是計算身高的均值。

首先應該先寫出分組條件:

condition = df.Weight > df.Weight.mean()
df.groupby(condition)
['Height'].mean() out: Weight False 159.034646 True 172.705357 Name: Height, dtype: float64

練一練
請根據上下四分位數分割,將體重分為high、normal、low三組,統計身高的均值。

#從索引可以看出,其實最後產生的結果就是按照條件列表中元素的值(此處是True和False)來分組,下面用隨機傳入字母序列來驗證這一想法:
item = np.random.choice(list('abc'), df.shape[0])
df.groupby(item)['Height'].mean()

out:
a 164.407143 b 161.930508 c 163.355882 Name: Height, dtype: float64 #此處的索引就是原先item中的元素,如果傳入多個序列進入groupby,那麼最後分組的依據就是這兩個序列對應行的唯一組合: df.groupby([condition, item])['Height'].mean() out: Weight False a 159.822222 b 158.338636 c 159.082979 True a 172.660000 b 172.466667
c 172.919048 Name: Height, dtype: float64

Groupby物件
最終具體做分組操作時,所呼叫的方法都來自於pandas中的groupby物件

gb = df.groupby(['School', 'Grade'])

out:
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x0000024E9F837288>

內建聚合函式
定義在groupby物件的聚合函式,因為它的速度基本都會經過內部的優化,使用功能時應當優先考慮。根據返回標量值的原則,包括如下函式:max/min/mean/median/count/all/any/idxmax/idxmin/mad/nunique/skew/quantile/sum/std/var/sem/size/prod。

gb = df.groupby('Gender')['Height']
gb.idxmin()

out:
Gender
Female    143
Male      199
Name: Height, dtype: int64

gb.quantile(0.95)

out:
Gender
Female    166.8
Male      185.9
Name: Height, dtype: float64

變換和過濾

變換函式與transform方法

變換函式的返回值為同長度的序列,最常用的內建變換函式是累計函式:cumcount/cumsum/cumprod/cummax/cummin,它們的使用方式和聚合函式類似,只不過完成的是組內累計操作。此外在groupby物件上還定義了填充類和滑窗類的變換函式。

gb.cummax().head()

out:
	Height	Weight
0	158.9	46.0
1	166.5	70.0
2	188.9	89.0
3	NaN	46.0
4	188.9	89.0

練一練

groupby物件中,rank方法也是一個實用的變換函式,請查閱它的功能並給出一個使用的例子。

#現對身高和體重進行分組標準化,即減去組均值後除以組的標準差:
gb.transform(lambda x: (x-x.mean())/x.std()).head()

out:
	Height	Weight
0	-0.058760	-0.354888
1	-1.010925	-0.355000
2	2.167063	2.089498
3	NaN	-1.279789
4	0.053133	0.159631

組索引與過濾

過濾在分組中是對於組的過濾,而索引是對於行的過濾,在第二章中的返回值,無論是布林列表還是元素列表或者位置列表,本質上都是對於行的篩選,即如果篩選條件的則選入結果的表,否則不選入。

組過濾作為行過濾的推廣,指的是如果對一個組的全體所在行進行統計的結果返回True則會被保留,False則該組會被過濾,最後把所有未被過濾的組其對應的所在行拼接起來作為DataFrame返回。

在groupby物件中,定義了filter方法進行組的篩選,其中自定義函式的輸入引數為資料來源構成的DataFrame本身,在之前例子中定義的groupby物件中,傳入的就是df[[‘Height’, ‘Weight’]],因此所有表方法和屬性都可以在自定義函式中相應地使用,同時只需保證自定義函式的返回為布林值即可。

# 例如,在原表中通過過濾得到所有容量大於100的組:
gb.filter(lambda x: x.shape[0] > 100).head()

out:
	Height	Weight
0	158.9	46.0
3	NaN	41.0
5	158.0	51.0
6	162.5	52.0
7	161.9	50.0