在Python Ibis框架中按指定列实现累计求和(不可用Pandas)
问题
我有一个庞大且复杂的Ibis脚本,其中一部分用于计算衍生列。最终需要通过ibis.to_sql(t)生成SQL语句,因此无法使用Pandas。
现有测试表定义如下:
import ibis from ibis import _ ibis.options.interactive = True t = ibis.memtable( { "fruit": ["apple", "apple", "banana", "orange"], "price": [0.5, 0.5, 0.25, 0.33], "order": [1, 2, 3, 4], } )
需要实现的结果是新增cumsum_price列,按order列顺序计算price的累计求和,最终输出如下结构的结果:
┏━━━━━━━━┳━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━┓ ┃ fruit ┃ price ┃ order┃ cumsum_price┃ ┡━━━━━━━━╇━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━┩ │ string │ float64│ int64│ float64 │ ├────────┼────────┼──────┼────────────┤ │ apple │ 0.50 │ 1 │ 0.50 │ │ apple │ 0.50 │ 2 │ 1.0 │ │ banana │ 0.25 │ 3 │ 1.25 │ │ orange │ 0.33 │ 4 │ 1.58 │ └────────┴────────┴──────┴────────────┘
我尝试了以下写法,但无法生效:
t = t.mutate(cumsum_price = t['price']+t.cumsum_price.lag().over(order_by=[t.order]))
再次说明:不能使用Pandas,必须通过Ibis实现并生成对应的SQL。
解决方案
你的写法错误在于试图引用尚未创建的cumsum_price列,Ibis中计算累计求和不需要手动递归相加,直接使用窗口函数的cumsum()方法即可。
正确的实现代码如下:
# 按order列排序,计算price的累计求和 t_with_cumsum = t.mutate( cumsum_price = t.price.cumsum().over(order_by=[t.order]) ) # 查看结果 print(t_with_cumsum) # 生成对应的SQL语句 print(ibis.to_sql(t_with_cumsum))
说明:
cumsum()是Ibis内置的窗口聚合函数,用于计算累计求和,配合over(order_by=[t.order])指定排序依据,就能实现按order顺序累计price的需求。- 这种写法会生成标准的SQL窗口函数语法(类似
SUM(price) OVER (ORDER BY "order") AS cumsum_price),完全符合你的需求,不需要依赖Pandas。
执行上述代码后,得到的结果会和你预期的一致,同时通过ibis.to_sql()可以生成对应的SQL语句,适用于你的复杂脚本场景。
内容的提问来源于stack exchange,提问作者KRL
相关产品推荐
相关产品推荐

