科普:pandas 中的类 SQL语句:transaction.groupby(“card_id“)[‘purchase_day‘].diff()

python 复制代码
transaction['purchase_day_diff'] = transaction.groupby("card_id")['purchase_day'].diff()

等价于 SQL 里的窗口函数:

sql 复制代码
SELECT 
    card_id,
    purchase_day,
    -- 按用户分组,按时间排序,取上一行的 purchase_day,即LAG使时间滞后一步(后移一格),反之,LEAD = 超前一步(前移一格)
    LAG(purchase_day) OVER (PARTITION BY card_id ORDER BY purchase_day) AS prev_day,
    -- 当前天 - 上一天 = 时间差
    purchase_day - LAG(purchase_day) OVER (PARTITION BY card_id ORDER BY purchase_day) AS purchase_day_diff
FROM transaction

一、该python语句等价于 SQL 里的窗口函数

groupby(列).diff() = SQL 的 LAG() 窗口函数,算组内行与行的差值!

1、实现功能

按每个用户分组,把他的交易按时间排序,然后算:当前交易日期 - 上一次交易日期 = 间隔天数


假设交易表:

card_id purchase_day
user1 10
user1 15
user1 20
user2 5
user2 9

执行:

python 复制代码
groupby("card_id")['purchase_day'].diff()

得到:

card_id purchase_day purchase_day_diff
user1 10 NaN(第一笔,没有上一笔)
user1 15 5(15-10)
user1 20 5(20-15)
user2 5 NaN
user2 9 4(9-5)

2、对应 SQL

运行结果一模一样

sql 复制代码
SELECT
    card_id,
    purchase_day,
    purchase_day - LAG(purchase_day) OVER(PARTITION BY card_id ORDER BY purchase_day) AS purchase_day_diff
FROM transaction

结果:

card_id purchase_day purchase_day_diff
user1 10 NULL
user1 15 5
user1 20 5
user2 5 NULL
user2 9 4

这里的窗口函数做了什么?

  1. 按用户分窗口:OVER(PARTITION BY)
  2. 排序:ORDER BY
  3. LAG 取上一行:LAG(purchase_day)
  4. 手动减法 = diff:purchase_day - LAG(purchase_day)

二、SQL的窗口函数

前面提到SQL的窗口函数,这里专门讲讲。

窗口函数 = 对一组内行与行之间互相计算,但不把多行压成一行(保留原行数)

对比:

  • GROUP BY:多行 → 一行(汇总)
  • 窗口函数:多行 → 还是多行(行与行之间计算)

1、普通聚合(GROUP BY)------压扁

sql 复制代码
SELECT card_id, SUM(amount) FROM transaction GROUP BY card_id

结果:一个用户一行

2、窗口函数 ------不压扁,每行都保留

sql 复制代码
SELECT card_id, SUM(amount) OVER (PARTITION BY card_id)

结果:多少行,还是多少行,但每一行都带上了该用户的总和


窗口函数结构(固定格式)

sql 复制代码
函数() OVER (
    PARTITION BY 列1, 列2   -- 分组(窗口)
    ORDER BY 排序列         -- 组内排序
)

三部分:

  1. OVER:标志这是窗口函数
  2. PARTITION BY:把数据分成多个小组(窗口)
  3. ORDER BY:组内按什么顺序排

方式 结果行数 作用
GROUP BY 减少(每组1行) 汇总统计
窗口函数 不变(原行数) 行与行之间计算

三、其它类似的对应关系

1、核心对应规则

python 复制代码
df.groupby(分组列)[统计列].聚合函数()

完全等价 SQL:

sql 复制代码
SELECT 分组列, 聚合函数(统计列)
FROM df
GROUP BY 分组列

2、 对应举例

1)groupby + sum

python 复制代码
transaction.groupby("card_id")["purchase_amount"].sum()

SQL:

sql 复制代码
SELECT card_id, SUM(purchase_amount)
FROM transaction
GROUP BY card_id

含义:每个用户总消费金额


2)groupby + mean

python 复制代码
transaction.groupby("card_id")["purchase_amount"].mean()

SQL:

sql 复制代码
SELECT card_id, AVG(purchase_amount)
FROM transaction
GROUP BY card_id

含义:每个用户平均消费金额


3)groupby + count

python 复制代码
transaction.groupby("card_id")["purchase_amount"].count()

SQL:

sql 复制代码
SELECT card_id, COUNT(purchase_amount)
FROM transaction
GROUP BY card_id

含义:每个用户有多少笔交易(非空)


4)groupby + size

python 复制代码
transaction.groupby("card_id").size()

SQL:

sql 复制代码
SELECT card_id, COUNT(*)
FROM transaction
GROUP BY card_id

含义:每个用户总交易笔数(不管空值)


5)groupby + nunique(去重计数)

python 复制代码
transaction.groupby("card_id")["merchant_category_id"].nunique()

SQL:

sql 复制代码
SELECT card_id, COUNT(DISTINCT merchant_category_id)
FROM transaction
GROUP BY card_id

含义:每个用户消费过多少个不同商户类别


6)groupby + min / max

python 复制代码
transaction.groupby("card_id")["purchase_amount"].min()
transaction.groupby("card_id")["purchase_amount"].max()

SQL:

sql 复制代码
SELECT card_id, MIN(purchase_amount), MAX(purchase_amount)
FROM transaction
GROUP BY card_id

7)groupby + diff(本文开头提到的)

python 复制代码
transaction.groupby("card_id")["purchase_day"].diff()

SQL:

sql 复制代码
purchase_day - LAG(purchase_day) OVER (PARTITION BY card_id ORDER BY purchase_day)

3、多列聚合(pandas agg → SQL GROUP BY 多函数)

python 复制代码
transaction.groupby("card_id").agg({
    "purchase_amount": ["sum", "mean", "max"],
    "merchant_id": "nunique",
    "card_id": "size"
})

对应 SQL:

sql 复制代码
SELECT
    card_id,
    SUM(purchase_amount),
    AVG(purchase_amount),
    MAX(purchase_amount),
    COUNT(DISTINCT merchant_id),
    COUNT(*)
FROM transaction
GROUP BY card_id

4、它们是包pandas的API功能

上述提到的这些函数 全部属于 pandas

python 复制代码
groupby()
sum()
mean()
count()
size()
nunique()
min()
max()
diff()
agg()

👉 全部是 pandas.DataFrame / pandas.Series 的方法

你必须导入 pandas 才能用

python 复制代码
import pandas as pd

没有这句,上面所有函数都不存在

它们是 pandas 自己实现的数据分析 API ,语法风格模仿 SQL,但底层是 pandas。


附:取行、取列、新建列

回到开头的这句代码:

python 复制代码
transaction['purchase_day_diff'] = transaction['purchase_day']...

左侧的中括号中是字符串!!

在交易表 transaction 里,新建一列 ,名字叫 purchase_day_diff

然后把右边计算好的"时间差"数据存进去。

pandas 设计就是:
中括号里写字符串 = 操作列
中括号里写数字 = 操作行


中括号里写字符串:右边取列,左边建列!

左边(等号左边)

python 复制代码
transaction['purchase_day_diff'] =...

新建一列 ,名字叫 purchase_day_diff

右边(等号右边)

python 复制代码
...= transaction['purchase_day']...

取出 purchase_day 这一列 用来计算


相关推荐
梦想与想象-广州大智汇2 小时前
MySQL 同步数据到 ClickHouse 方案对比分析
数据库·mysql·clickhouse
雨墨✘2 小时前
如何解决SQL多表查询数据重复问题_使用DISTINCT与JOIN优化
jvm·数据库·python
u0107475462 小时前
JavaScript 递归调用栈深度解析与层级遍历陷阱详解
jvm·数据库·python
herinspace2 小时前
管家婆实用帖-如何使用ping命令检测网络环境
网络·数据库·人工智能·学习·excel·语音识别
星空椰2 小时前
Windows 安装 PostgreSQL 数据库
数据库·postgresql
Elastic 中国社区官方博客2 小时前
用于 IntelliJ IDEA 的新 ES|QL 插件
java·大数据·数据库·ide·elasticsearch·搜索引擎·intellij-idea
疯狂成瘾者2 小时前
LangChain Middleware 技术解析:从“插槽机制”到 Agent 运行时控制
数据库·python·langchain
七夜zippoe2 小时前
OpenClaw 飞书深度集成:多维表格
数据库·算法·飞书·集成·openclaw
A-刘晨阳2 小时前
当数据学会“秒回“:工业4.0时代的实时计算革命
开发语言·数据库·perl