ibis 向下进行缺失值填充
import ibis
import ibis.selectors as s
from ibis import _
ibis.options.interactive = True
con=ibis.duckdb.connect()
#10.3.1
print(ibis.__version__)
# three =con.read_xlsx("/mnt/c/Users/xuefl/Downloads/24年报损疫苗tj.xlsx")
# mon3=con.read_csv('/mnt/d/2021/3.csv')
# con.list_tables()
test=con.read_xlsx("/mnt/c/Users/xuefl/Downloads/工作簿1.xlsx")
# 创建窗口对象
window = ibis.window(
preceding=None, # 无限前行
following=0, # 当前行
order_by='rowid' # 使用行ID确保正确的顺序,如果你的表没有rowid,可能需要先添加一个
)
# 实现向下填充,类似dplyr的fill(.direction = 'down')
test = (
test
.mutate(rowid=ibis.row_number().over())
.mutate(
A_filled=lambda t: t.A.max().over(window)
)
# 可以选择删除rowid列和原始A列,或重命名A_filled为A
.drop('rowid')
.rename(A_filled='A')
)
#####
def fill(self, order_by='rowid'):
"""
对当前列执行向下填充操作(将空值用前面的非空值填充)
参数:
self: 当前列 (ibis Column 对象)
order_by: 用于排序的列名或表达式,默认为 'rowid',可以是字符串或 ibis 表达式
返回:
填充后的 ibis Expr 对象
注意:
如果 order_by 是字符串且列不存在,将使用自然顺序
"""
# 创建窗口
if isinstance(order_by, str):
# 使用指定列排序
window = ibis.window(
preceding=None, # 从开头开始
following=0, # 到当前行结束
order_by=order_by # 按指定列排序
)
else:
# 如果 order_by 是表达式
window = ibis.window(
preceding=None,
following=0,
order_by=order_by
)
# 使用 max() 获取前面的非空值进行填充
return self.max().over(window)
# 将 fill 方法绑定到 Value 类型
ibis.expr.types.Value.fill = fill
# 读取数据
test = con.read_xlsx("/mnt/c/Users/xuefl/Downloads/工作簿1.xlsx")
# 为表添加 rowid 列并使用它进行填充
result = (
test
.mutate(rowid=ibis.row_number().over(ibis.window(order_by=ibis.literal(1))))
.mutate(A=_.A.fill())
)
######
import ibis
import ibis.selectors as s
from ibis import _
def fill(table, column_name, order_by='rowid'):
"""
对指定列执行向下填充操作
参数:
table: ibis Table 对象
column_name: 要填充的列名 (字符串)
order_by: 用于排序的列名,默认为 'rowid'
返回:
带有填充结果的 ibis Table 对象
"""
# 定义窗口函数
window = ibis.window(
preceding=None, # 从开头开始
following=0, # 到当前行结束
order_by=order_by # 按指定列排序
)
# 执行填充操作
return (
table
.mutate(rowid=ibis.row_number().over()) # 添加临时行号
.mutate(
**{f"{column_name}_filled": lambda t: t[column_name].max().over(window)}
)
.drop('rowid') # 删除临时列
.rename(**{column_name: f"{column_name}_filled"}) # 重命名回原列名
)
# 读取数据
test = con.read_xlsx("/mnt/c/Users/xuefl/Downloads/工作簿1.xlsx")
# 调用fill函数
result = fill(test, 'A') # 对A列进行向下填充
评论
发表评论