数据集合与分组操作:数据聚合,逐列及多函数应用,返回不含行索引的聚合数据, 数据透视表与交叉表(crosstab)

阅读: 评论:0

数据集合与分组操作:数据聚合,逐列及多函数应用,返回不含行索引的聚合数据, 数据透视表与交叉表(crosstab)

数据集合与分组操作:数据聚合,逐列及多函数应用,返回不含行索引的聚合数据, 数据透视表与交叉表(crosstab)

2.1 数据聚合

聚合是指所有根据数组产生标量值的数据转换过程。就像mean count min sum等,

函数描述
count分组中的非NA 值数量
sum非NA值的累计和
mean非NA 值的均值
median非NA 值的算术中位数
std,var无偏的(n-1 分母)标准差和方差
min max非NA 值的最大值最小值
prod非NA 值 的乘积
first,last非NA 值 的第一个和最后一个值。

你可以自定义聚合,并在调用已经在分组对象上定义好的方法。例如,quantile 可用计算series 或 dataframe 列的样本分位数

分位数(Quantile),亦称分位点,是指将一个随机变量的概率分布范围分为几个等份的数值点,常用的有中位数(即二分位数)、四分位数、百分位数等。

尽管quantile并不是显式的为GroupBy 对象的函数,但是series的方法,因此也可以用于聚合。

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)})
dfkey1	key2	data1	data2
0	a	one	-0.603123	1.810936
1	a	two	0.462399	0.172707
2	b	one	0.998915	-1.275746
3	b	two	2.649937	-0.188244
4	a	one	-1.637420	0.921537grouped&#upby('key1')
grouped['data1'].quantile(0.9)
key1
a    0.249294
b    2.484835
Name: data1, dtype: float64def peak_to_peak(arr):             # 用自己的聚合函数,要把函数传递给aggregate or agg 方法。return arr.max()-arr.min()
grouped.agg(peak_to_peak)data1	data2
key1		
a	2.099819	1.638229
b	1.651022	1.087502grouped.describe()      # 一些方法比如这个也是有效的,尽管不是聚合函数data1	data2
count	mean	std	min	25%	50%	75%	max	count	mean	std	min	25%	50%	75%	max
key1																
a	3.0	-0.592715	1.049948	-1.637420	-1.120271	-0.603123	-0.070362	0.462399	3.0	0.968393	0.820119	0.172707	0.547122	0.921537	1.366236	1.810936
b	2.0	1.824426	1.167449	0.998915	1.411671	1.824426	2.237182	2.649937	2.0	-0.731995	0.768980	-1.275746	-1.003870	-0.731995	-0.460120	-0.188244

2.1.1 逐列及多函数应用

tips&#ad_csv('tips.csv',sep='t')
tips['tip_pct']=tips['tip']/tips['total_bill']        # 增加一个小费比例
tips.head()total_bill	tip	smoker	day	time	size	tip_pct
0	16.99	1.01	No	Sun	Dinner	2	0.059447
1	10.34	1.66	No	Sun	Dinner	3	0.160542
2	21.01	3.50	No	Sun	Dinner	3	0.166587
3	23.68	3.31	No	Sun	Dinner	2	0.139780
4	24.59	3.61	No	Sun	Dinner	4	0.146808grouped&#upby(['day','smoker'])
grouped_pct=grouped['tip_pct']     # 将函数名以字符串的形式传入
grouped_pct.agg('mean')
day   smoker
Fri   No        0.151650Yes       0.174783
Sat   No        0.158048Yes       0.147906
Sun   No        0.160113Yes       0.187250
Thur  No        0.160298Yes       0.163863
Name: tip_pct, dtype: float64grouped_pct.agg(['mean','std',peak_to_peak])      # 传递的是函数或函数名的列表,获得列名是这些函数名的dataframe mean	std	peak_to_peak
day	smoker			
Fri	No	0.151650	0.028123	0.067349Yes	0.174783	0.051293	0.159925
Sat	No	0.158048	0.039767	0.235193Yes	0.147906	0.061375	0.290095
Sun	No	0.160113	0.042347	0.193226Yes	0.187250	0.154134	0.644685
Thur	No	0.160298	0.038774	0.193350Yes	0.163863	0.039389	0.151240grouped_pct.agg([('foo','mean'),('bar',np.std)])    # (name.function) 第一个元素作为dataframe的列名foo	bar
day	smoker		
Fri	No	0.151650	0.028123Yes	0.174783	0.051293
Sat	No	0.158048	0.039767Yes	0.147906	0.061375
Sun	No	0.160113	0.042347Yes	0.187250	0.154134
Thur	No	0.160298	0.038774Yes	0.163863	0.039389functions=['count','mean','max']                             # 应用到所有列上的函数列表,
result=grouped['tip_pct','total_bill'].agg(functions)
resulttip_pct	                     total_billcount	mean	max	               count	mean	max
day	smoker						
Fri	No	4	0.151650	0.187735	4	18.420000	22.75Yes	15	0.174783	0.263480	15	16.813333	40.17
Sat	No	45	0.158048	0.291990	45	19.661778	48.33Yes	42	0.147906	0.325733	42	21.276667	50.81
Sun	No	57	0.160113	0.252672	57	20.506667	48.17Yes	19	0.187250	0.710345	19	24.120000	45.35
Thur	No	45	0.160298	0.266312	45	17.113111	41.19Yes	17	0.163863	0.241255	17	19.190588	43.11result['tip_pct']                          # 产生的dataframe 有分层列,这与聚合每一列在通过concat将结果拼接在一起是相同的count	mean	max
day	smoker			
Fri	No	4	0.151650	0.187735Yes	15	0.174783	0.263480
Sat	No	45	0.158048	0.291990Yes	42	0.147906	0.325733
Sun	No	57	0.160113	0.252672Yes	19	0.187250	0.710345
Thur	No	45	0.160298	0.266312Yes	17	0.163863	0.241255ftuples=[('Durchschnitt','mean'),('Abweichung',np.var)]         # 就是传递有自定义名称的元组列表。
grouped['tip_pct','total_bill'].agg(ftuples)tip_pct	total_bill
Durchschnitt	Abweichung	Durchschnitt	Abweichung
day	smoker				
Fri	No	0.151650	0.000791	18.420000	25.596333Yes	0.174783	0.002631	16.813333	82.562438
Sat	No	0.158048	0.001581	19.661778	79.908965Yes	0.147906	0.003767	21.276667	101.387535
Sun	No	0.160113	0.001793	20.506667	66.099980Yes	0.187250	0.023757	24.120000	109.046044
Thur	No	0.160298	0.001503	17.113111	59.625081Yes	0.163863	0.001551	19.190588	69.808518grouped.agg({'tip_pct':['min','max','mean','std'],              # 将不同的函数应用到一个或多个列上的字典就像'size':'sum'})                                      # ,传递有列名与函数对应关系tip_pct	                          sizemin	max	        mean	    std	       sum
day	smoker					
Fri	No	0.120385	0.187735	0.151650	0.028123	9Yes	0.103555	0.263480	0.174783	0.051293	31
Sat	No	0.056797	0.291990	0.158048	0.039767	115Yes	0.035638	0.325733	0.147906	0.061375	104
Sun	No	0.059447	0.252672	0.160113	0.042347	167Yes	0.065660	0.710345	0.187250	0.154134	49
Thur	No	0.072961	0.266312	0.160298	0.038774	112Yes	0.090014	0.241255	0.163863	0.039389	40

2.1.2 返回不含行索引的聚合数据

前面的例子中,聚合数据返回时都是带有索引的,有时索引是分层的,由唯一的分组件联合形成。因为不是所有的情况都要索引,通过传递 ax_index = False 来禁用分组键作为索引的行为。

upby(['day','smoker'],as_index=False).mean() # == upby(['day','smoker']).mean().reset_index()day	smoker	total_bill	tip	size	tip_pct
0	Fri	No	18.420000	2.812500	2.250000	0.151650
1	Fri	Yes	16.813333	2.714000	2.066667	0.174783
2	Sat	No	19.661778	3.102889	2.555556	0.158048
3	Sat	Yes	21.276667	2.875476	2.476190	0.147906
4	Sun	No	20.506667	3.167895	2.929825	0.160113
5	Sun	Yes	24.120000	3.516842	2.578947	0.187250
6	Thur	No	17.113111	2.673778	2.488889	0.160298
7	Thur	Yes	19.190588	3.030000	2.352941	0.163863

3.1 数据透视表与交叉表

数据透视表是电子表格程序和其他数据分析软件中常见的数据汇总工具。更加一个或多个键聚合一张表的数据,将数据在矩形格式中排列,其中一些分组件是沿着行的,另一些沿着列。

在pandas中透视表透过groupby 工具以及使用分层索引的重塑操作实现。dataframe 有一个pivot_table 方法,并且还有一个顶层的pandas.pivot_table 函数,为groupby提供了一个方便的接口,还可以添加部分总计,也叫边距。。。啥啥啥啥啥

tips.pivot_table(index=['day','smoker'])  # 计算一张在行方向上按day and smoker排列的分组平均值
size	tip	tip_pct               	total_bill    # upby(['day','smoker']).mean() 跟这个一样欸
day	smoker				
Fri	No	2.250000	2.812500	0.151650	18.420000Yes	2.066667	2.714000	0.174783	16.813333
Sat	No	2.555556	3.102889	0.158048	19.661778Yes	2.476190	2.875476	0.147906	21.276667
Sun	No	2.929825	3.167895	0.160113	20.506667Yes	2.578947	3.516842	0.187250	24.120000
Thur	No	2.488889	2.673778	0.160298	17.113111Yes	2.352941	3.030000	0.163863	19.190588tips.pivot_table(['tip_pct','size'],index=['time','day'],columns='smoker',margins=True) # z在tip_pct,size 列聚合,根据time分组size	t                    ip_pct       # 将 smoker放到表的列,将day 放到表的行。
smoker	          No	Yes	All	                         No	Yes	All     # 添加margins=True, 来扩充这个表来包含部分统计
time	day						
Dinner	Fri	2.000000	2.222222	2.166667	0.139622	0.165347	0.158916   # 这里All的值是均值,就是不考虑分组了Sat	2.555556	2.476190	2.517241	0.158048	0.147906	0.153152Sun	2.929825	2.578947	2.842105	0.160113	0.187250	0.166897Thur	2.000000	NaN	2.000000	0.159744	NaN	0.159744
Lunch	Fri	3.000000	1.833333	2.000000	0.187735	0.188937	0.188765Thur	2.500000	2.352941	2.459016	0.160311	0.163863	0.161301
All		2.668874	2.408602	2.569672	0.159328	0.163196	0.160803tips.pivot_table('tip_pct',index=['time','smoker'],columns='day',aggfunc=len,margins=True,fill_value=0)day	Fri	Sat	Sun	Thur	All        # 使用不同聚合函数时,将函数传递给aggfunc就行,传递len获得一张分组大小的交叉表
time	smoker					
Dinner	No	3	45	57	1	106.0                 Yes	9	42	19	0	70.0
Lunch	No	1	0	0	44	45.0Yes	6	0	0	17	23.0
All		19	87	76	62	244.0
pivot_table参数描述
values需要聚合的列,默认聚合所有数值型列
index在结果透视表的行上进行分组的列名或其他分组键
columns在结果透视表的列上进行分组的列名或其他分组键。
aggfunc聚合函数或函数列表,默认时mean 可以是groupby的任意有效函数
fill_value替换缺失值
dropna如果为True,不含所有条目都为NA的列
margins添加ALL,默认False

3.2 交叉表:crosstab

这个是数据透视表的一个特殊情况,计算的是分组中的频率,

from io import StringIO
data = """
Sample  Nationality  Handedness
1   USA  Right-handed
2   Japan    Left-handed
3   USA  Right-handed
4   Japan    Right-handed
5   Japan    Left-handed
6   Japan    Right-handed
7   USA  Right-handed
8   USA  Left-handed
9   Japan    Right-handed
10  USA  Right-handed"""
data = pd.read_table(StringIO(data), sep='s+')
data
Sample	Nationality	Handedness
0	1	USA	Right-handed
1	2	Japan	Left-handed
2	3	USA	Right-handed
3	4	Japan	Right-handed
4	5	Japan	Left-handed
5	6	Japan	Right-handed
6	7	USA	Right-handed
7	8	USA	Left-handed
8	9	Japan	Right-handed
9	10	sstab(data.Nationality, data.Handedness, margins=True)   # 虽然可以使用pivot_table,但crosstab更加方便
Handedness	Left-handed	Right-handed	All
Nationality			
Japan	2	3	5
USA	    1	4	5
All	    3	7	10# corsstab 的前两个参数可以是数值,series或数组的列表
pd.crosstab([tips.time, tips.day], tips.smoker, margins=True)  # 额,,又是这个
smoker     	No	Yes	All
time	day			
Dinner	Fri	3	9	12Sat	45	42	87Sun	57	19	76Thur	1	0	1
Lunch	Fri	 1	6	7Thur	44	17	61
All		151	93	244

本文发布于:2024-02-05 01:25:08,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170720883161776.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:数据   不含   透视   函数   索引
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23