科普: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 这一列 用来计算


相关推荐
梦想的颜色11 小时前
MySQL 数据存储结构与查询执行生命周期深度解析
运维·数据结构·数据库·mysql·线程·优化
电商API_1800790524711 小时前
免 TOP 入驻,第三方淘宝商品详情 API 快速接入与代码示例
java·大数据·开发语言·数据库·爬虫·数据分析
神龙斗士24011 小时前
增删改查操作
数据库·mysql
Elastic 中国社区官方博客11 小时前
13.7万人,零人工决策:使用 Elasticsearch 实现智能体驱动的灾害响应系统
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
yuzhiboyouye11 小时前
sql增删改查怎么写?有时会不会有联表查询的增删查改
数据库·sql
jingyu飞鸟12 小时前
openEuler 22.03 LTS SP4安装华为opengauss 22.03 LTS版本数据库,一键复制安装使用,保姆级教程
数据库·华为
IvorySQL12 小时前
【HOW 2026 分论坛演讲】PG/IvorySQL私有云中实践
数据库·人工智能·sql·postgresql
SAP庖丁解码12 小时前
【采购申请的校验——成本中心范围】
数据库
雪的季节12 小时前
HTTP 和 HTTPS 五大核心区别
数据库·http·https
GottdesKrieges13 小时前
OceanBase迁移用户及其权限配置
数据库·oceanbase