3.3 有序分组

 

3.2 非等值分组


3.3.1 按位置分组

员工每 10 个分一组,把姓氏的众数作为该组的姓氏

SPL

A
1 =file(“EMPLOYEE.csv”).import@tc()
2 =A1.group((#-1)\10).new(#:GID,~.mode(SURNAME):SURNAME)

SPL 利用”#”来得到分组键,不需要单独计算一列分组键

SQL

SELECT GRP, SURNAME
FROM (
    SELECT CEIL(rownum/10) AS grp, SURNAME, COUNT(*) AS count,
        ROW_NUMBER() OVER (PARTITION BY CEIL(rownum/10) ORDER BY COUNT(*) DESC) AS rn
    FROM EMPLOYEE
    GROUP BY CEIL(rownum/10), SURNAME)
WHERE rn = 1;

Python

emp=pd.read_csv('../EMPLOYEE.csv')
pos_seq=[i//10foriinrange(len(emp))]
group_surname=emp.groupby(pos_seq)['SURNAME'].apply(lambdax:x.value_counts().idxmax())

Python 是衍生出一列,然后根据衍生列分组。

3.3.2 按序号分组

员工分成 10 组,把姓氏的众数作为该组的姓氏

SPL

A
1 =file(“EMPLOYEE.csv”).import@tc()
2 =A1.group@n(#%10+1).new(#:GID,~.mode(SURNAME):SURNAME)

@n 选项是按序号分组,这时要保证分组键值是自然数且从 1 开始,能提高分组效率。

SQL

SQL 没有类似的方法提高分组效率。

Python

Python 没有类似的方法提高分组效率。

3.3.3 值变化分组

找出序列中的连续数字序列

SPL

A B
1 [7,5,5,7,13,15,16,17,13,5,6,7,8,17,6,10,11,11,18,15]
2 =A1.group@o(~-#).select(~.len()>1) /[[15,16,17],[5,6,7,8],[10,11]]

groups@o() 方法依次扫描整个序列,当分组键值和上一个成员的分组键相同时,则将该成员加入到当前的分组子集,如果分组键值发生变化了,则产生一个新的分组子集。

SQL

SQL 中没有现成的方法来完成这个任务。

Python

lst=[7,5,5,7,13,15,16,17,13,5,6,7,8,17,6,10,11,11,18,15]
diffs=[j-ifori,jinenumerate(lst)]
groups=pd.Series(diffs).diff().ne(0).cumsum()
g_list=pd.Series(lst).groupby(groups).agg(list)
result=g_list[g_list.apply(lambdax:len(x)>1)].tolist()

Python 还是要烧脑去构造一个衍生列来分组。

3.3.4 条件变化分组

股票最长连续上涨天数

SPL

A
1 =file(“STOCK.csv”).import@tc()
2 =A1.group@i(CLOSING<=CLOSING[-1]).max(~.len())-1

group@i() 的分组键是个表达式,每当计算出 true 时则产生一个新的分组子集,也就是满足某个条件时就重新分一组。因为分组的第 1 条记录并不上涨,所以最后要减 1。

SQL

SQL 中没有现成的方法来完成这个任务。

Python

stock = pd.read_csv('../STOCK.csv')
stock['UP'] = stock['CLOSING'].diff() > 0
up_streak = stock.groupby((~stock['UP']).cumsum())['UP'].cumsum().where(stock['UP'], 0)
max_streak = up_streak.max()

Python 还是老方法,构造一个衍生列来完成计算。


3.4 逆分组
SPL SQL Python 代码示例对比