pandasgroupby分组对象的组内排序解决⽅案
问题:
根据数据某列进⾏分组,选择其中另⼀列⼤⼩top-K的的所在⾏数据
解析:
求解思路很清晰,即先⽤groupby对数据进⾏分组,然后再根据分组后的某⼀列进⾏排序,选择排序结果后的top-K结果
案例:
取⼀下dataframe中B列各对象中C值最⾼所在的⾏
df = pd.DataFrame({"A": [2, 3, 5, 4], "B": ['a', 'b', 'b', 'a'], "C": [200801, 200902, 200704, 201003]})
Groupby的基本功能介绍
groupby以后返回DataFrameGroupBy对象,实际上还没有进⾏任何计算,只是⼀个暂时存储的容器,
[upby('B')
[Out]&roupby.DataFrameGroupBy object at 0x11800f588>
对groupby结果进⾏简单的列选取返回的也是DataFrameGroupBy/SeriesGroupBy对象,⽆法可视化
[upby('B')['A']  # 返回SeriesGroupBy对象
[Out]&roupby.SeriesGroupBy object at 0x117f6b630>
[upby('B')['A','C']  # 返回DataFrameGroupBy对象
[Out]&roupby.DataFrameGroupBy object at 0x117fb84e0>
需要对DataFrameGroupBy进⾏计数、统计、agg聚合计算、apply映射计算和transform等操作,才能⽣成可视化的数据(下⽂仅以count和size函数为例展⽰,不涉及其它的操作)
[In] df.groupby('B', as_index=False)['A'].count()  # 组内数据统计
[Out] B A
0 a 2
1 b 2
[In] df.groupby('B')['A'].size().reset_index(name='Size') # 组内数据统计,size和count的⼀个显著区别在于count不考虑Nan,size考虑Nan
[Out] B Size
0  a 2
1  b 2
解决⽅案⼀:
对DataFrameGroupBy对象,⽤apply函数进⾏某列的sort_values排序,再选出其中的最⼤值所在⾏
# 返回值是⼀个带有multiindex的dataframe数据,其中level=0为groupby的by列,⽽level=1为原index
[In] df.groupby('B').apply(lambda x: x.sort_values('C', ascending=False))
[Out] A B C
B
a 3 4 a 201003
0 2 a 200801
b 1 3 b 200902
2 5 b 200704
# 通过设置group_keys参数对multiindex进⾏优化
[In] df.groupby('B', group_keys=False).apply(lambda x: x.sort_values('C', ascending=False))
[Out] A B  C
3 4 a 201003
0 2 a 200801
1 3 b 200902
2 5 b 200704
# 再次groupby,并调⽤内置的first()⽅法,取最⼤值
[In] df.groupby('B', group_keys=False).apply(lambda x: x.sort_values('C', ascending=False)).groupby('B').first().reset_index()
[Out]  B A  C
0 a 4 201003
1 b 3 200902
解决⽅案⼆:
先对B进⾏整体的sort_values,在groupy取值
[In] df.sort_values('C', ascending=False).groupby('B').first().reset_index()
[Out]  B A  C
0 a 4 201003
1 b 3 200902
问题拓展:
groupby分组以上仅解决了Top-1的问题,如果是Top-k呢?
答案:将first()函数变为head()函数
[In] df.sort_values('C', ascending=False).groupby('B').head(2)
[Out] A B C
3 4 a 201003
1 3 b 200902
0 2 a 200801
2 5 b 200704
总结:
1、⽅案⼆,即先排序再groupby取值更⽅便
2、pandas中API众多,在实际使⽤时要捋清各步骤返回值的类型以⽅便记忆和联想
补充:pandas分组groupby、agg,排序sort,连接concat、join
连接concat和join
横向连接
df6.join(df7)
# df6的表格在前⾯,如需df7的表格在前需要交换位置
注意点:
1、concat这个⽅法,既可以实现横向连接,也可以实现纵向连接,通过设置axis的值来控制,axis=1表⽰的是横向连接,如果多个连接的对象,放在列表中
2、join也可以实现
纵向连接
注意点:
1、进⾏纵向合并的数据,需要⽤[]集合起来
2、ignore_index忽略原有的⾏索引,重新排列
3、drop_duplicates()删除重复数据
排序
#按照成绩排序
df10.sort_values('score')
#默认升序,从⼩到⼤
df10.sort_values(['score','group'],ascending=False,na_position='first')
#sort各个属性
参数描述
by字符串或者列表,如果是单个排序字段,使⽤的是字符串,如果指定多个,需要使⽤列表ascending True的时候,是按照升序,默认是升序
na_position表⽰的是空值的位置,'last'是默认的,'first'开始位置
分组
### groupby
for cls,data upby(['class','grade']):
print(cls)
print(data)
注意点:
1、groupby 如果指定的是⼀个列,如果是多个列[]
2、groupby返回的是⼀个对象,所以不能直接访问,可以使⽤for
筛选出分组之后的列
如果筛选出⼀列数据[[列名]],返回的是dataframe对象
如果筛选出多个列数据,直接使⽤[]和[[]]均可
总结[[列1,列2,。。。。]]
聚合函数 agg配合使⽤
函数描述
mean均值
max最⼤值
min最⼩值
median中位数
std标准差
count计数
skew偏度
quantile指定分位数
以上为个⼈经验,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。如有错误或未考虑完全的地⽅,望不吝赐教。

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