看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
本需求会涉及比较复杂的分组计算,同时还要将数据从列表读取到 Series 再从 Series 将结果转回列表。
有这样的一个列表:
l = [-8,-7, -2, -1, 1, 3, 2, -3 ,-1 ,-2 ,9 ,10, 2]
我们发现这个列表一段时全是正值,一段全是负值,我们需要在保证正负值段的整体顺序不变的情况下,在此段内容按绝对值从小到大排序,最终得到的结果为:
[-1, -2, -7, -8, 1, 2, 3, -1, -2, -3, 2, 9, 10]
我们的整体思路是用 Pandas 的 Series 相关方法来解决问题。首先需要按正负段进行分组,分组后在组内取各值的绝对值,再按绝对值的大小进行排序,最后输出重新排序的数据。
首先我们将列表数据构造为 Series:
import pandas as pd
import numpy as np
s = pd.Series(l)
s
'''
0 -8
1 -7
2 -2
3 -1
4 1
5 3
6 2
7 -3
8 -1
9 -2
10 9
11 10
12 2
dtype: int64
'''
用我们之前介绍过的方法,按正负值进行分组,我们可以先聚合成列表看一下分组结果:
(
s.groupby(s.map(np.sign).ne(s.map(np.sign).shift()).cumsum())
.agg(list)
)
'''
1 [-8, -7, -2, -1]
2 [1, 3, 2]
3 [-3, -1, -2]
4 [9, 10, 2]
dtype: object
'''
按下来就是按组内值的绝对值排序:
(
s.groupby(s.map(np.sign).ne(s.map(np.sign).shift()).cumsum())
.agg(lambda x: pd.Series(x).agg(lambda s: s.sort_values(ascending=False) if (np.sign(s)==-1).all() else s.sort_values()).to_list())
.explode()
.to_list()
)
# [-1, -2, -7, -8, 1, 2, 3, -1, -2, -3, 2, 9, 10]
以上代码的逻辑为,将得到的序列数据装载到 Series 里,然后判断这组数据的符号,如果是正号,按升序排列,如果是负号则按降序排列。
(完)
更新时间:2024-08-18 15:38:10 标签:pandas python 排序