modules.operators 模块帮助
本章节包含 modules.operators 包中常用「通用数据操作」模块的说明和示例,例如:
数值运算、字段计算等算子模块
表格列增删改、字段映射、组合计算等操作模块
ArithmeticOperator
模块简介与适用场景
ArithmeticOperator用于对两组数值(标量或数组)进行四则运算:加、减、乘、除。支持输入为
Number/NumberArray/TableSeries``(例如 pandas ``Series),输出类型与输入保持一致。典型适用场景:
在 Pipeline 中做简单数值计算(如安全系数、换算、差值、比例);
配合表格模块(如
AddTableColumns)完成 “先提取数列,再运算” 的流程;快速把两个数组进行逐元素计算。
端口说明
输入端口 -
InputNumbers1:第一组输入数值/数组(Number/NumberArray/TableSeries) -InputNumbers2:第二组输入数值/数组(Number/NumberArray/TableSeries)输出端口 -
OutputNumbers:运算结果(Number/NumberArray/TableSeries;通常与输入类型一致)
快速上手示例
from gdisdk.modules.operators import ArithmeticOperator
import numpy as np
calc = ArithmeticOperator(mname="Calc")
calc.operator = "+"
calc.InputNumbers1 = np.array([1, 2, 3])
calc.InputNumbers2 = np.array([4, 5, 6])
calc.execute()
result = calc.OutputNumbers.data
参数说明
参数名 |
类型 |
默认值 |
说明 |
|---|---|---|---|
|
|
|
运算符,分别表示加/减/乘/除。 |
Note
若
InputNumbers1或InputNumbers2为空(None),则OutputNumbers输出None。
在 pipeline 中的使用方式
from gdisdk.pipeline.pipeline import PipeLine
from gdisdk.modules.operators import ArithmeticOperator
pipe = PipeLine(app_name="CalcDemo", app_title="算术运算示例")
calc = ArithmeticOperator(mname="Calc")
calc.operator = "*"
# 也可以把其它模块的输出端口连到 calc 的输入端口
# links = other.OutputNumbers >> calc.InputNumbers1 | other2.OutputNumbers >> calc.InputNumbers2
# pipe.add_links(links)
# pipe.add_module(calc)
# pipe.run()
更多信息
ModifyTableColumns
模块简介与适用场景
ModifyTableColumns用于 “按列批量改值” :对输入表格的指定列写入新值,并输出修改后的表格。支持一次修改多列;每列的值可以是:
单一值:会广播到所有行;
列表/数组:按行写入,长度不足会用最后一个值补齐,长度超出会截断。
典型适用场景:
快速纠正或覆盖某些字段(例如把某列统一改为指定标记值);
为后续运算/绘图准备 “标准化后的列值”;
在 UI 中根据当前表格动态生成可编辑的列配置(该模块会根据输入表自动生成 schema)。
端口说明
输入端口 -
InputTable:输入表格(TableData/MaterialTable)输出端口 -
OutputTable:修改后的表格(TableData/MaterialTable)
快速上手示例:修改两列
import numpy as np
from gdisdk.dataclass.tables import TableData
from gdisdk.modules.operators import ModifyTableColumns
table = TableData(
{"a": [1, 2, 3], "b": [10, 20, 30]},
name="demo",
title="示例表",
)
mod = ModifyTableColumns(mname="Modify")
mod.InputTable = table
mod.modified_columns = {
"a": [100, 200], # 长度不足:会补齐为 [100, 200, 200]
"b": 999, # 单值:会广播为 [999, 999, 999]
}
out = mod.execute()
print(out.dataframe)
参数说明
参数名 |
类型 |
默认值 |
说明 |
|---|---|---|---|
|
|
|
要修改的列与目标值。key 可以写列 |
|
|
|
限制 UI 中可被编辑的列范围;不传则默认所有列都可编辑。 |
在 pipeline 中的使用方式
from gdisdk.pipeline.pipeline import PipeLine
from gdisdk.modules.readers import CsvReader
from gdisdk.modules.operators import ModifyTableColumns
pipe = PipeLine(app_name="ModifyColsDemo", app_title="修改表格列示例")
read_csv = CsvReader("Read")
read_csv.file = "example.csv"
read_csv.encoding = "auto"
mod = ModifyTableColumns("Modify")
mod.modified_columns = {"status": "OK"}
links = read_csv.OutputTable >> mod.InputTable
pipe.add_links(links)
pipe.run()
out_table = mod.OutputTable.data
更多信息
AddTableColumns
模块简介与适用场景
AddTableColumns用于给输入表格新增(或覆盖)若干列,并同步更新字段元数据(name/title/unit/description)。支持三种列值定义方式(优先级从高到低):
模板表达式**(``column_templates``):使用 **Python 表达式语法,并用
{列名}引用列;**静态值**(
column_values):直接给常量或数组;未提供值则填充
NaN。
支持 本地函数(local function):在模板中使用
function:函数名调用自定义函数(见下文示例与参数说明)。
Important
AddTableColumns的模板语法已更新为 Python 表达式(逐行求值),这与旧的 “格式化字符串/Excel-like” 写法 不兼容。旧写法(不再可用):
"L{_row_number+1}"、"BH{_row_number+1:03d}"、"{bore_id}-{_row_number+1}"。新写法(推荐):
"'L' + str({_row_number+1})"、"'BH' + str({_row_number+1}).zfill(3)"、"{bore_id} + '-' + str({_row_number+1})"。
端口说明
输入端口 -
InputTable:输入表格(TableData)输出端口 -
OutputTable:输出表格(新增/覆盖列后的TableData,并更新字段元数据)
快速上手示例 1:用模板新增计算列
from gdisdk.dataclass.tables import TableData
from gdisdk.modules.operators import AddTableColumns
table = TableData({"Amount": [10, 20, 30], "Tax": [1, 2, 3]})
add_cols = AddTableColumns("AddCols")
add_cols.InputTable = table
add_cols.column_names = [
{"name": "total", "title": "总额"},
]
add_cols.column_templates = {
"total": "{Amount} + {Tax}",
}
out = add_cols.execute()
print(out.dataframe)
快速上手示例 2:混合模板与静态值
from gdisdk.dataclass.tables import TableData
from gdisdk.modules.operators import AddTableColumns
table = TableData({"Price": [100, 200]})
add_cols = AddTableColumns("AddCols")
add_cols.InputTable = table
add_cols.column_names = [
{"name": "adjusted", "title": "调整后价格"},
{"name": "status", "title": "状态"},
]
add_cols.column_templates = {"adjusted": "{Price} * 1.1"}
add_cols.column_values = {"status": "Active"}
out = add_cols.execute()
常见模板写法速查
# 1) 引用列:{ColumnName}
# 2) 四则运算:{A} + {B} * 1.1
# 3) 组合表达式:({A} - {B}) / {C}
# 4) 字符串拼接:{first_name} + ' ' + {last_name}
# 5) 行号变量(Special Variables):{_row_number} # 0-based 行号:0,1,2,...
# 6) 生成序号(注意 str 转换):'L' + str({_row_number+1})
# 7) 自定义函数:function:my_func
column_templates = {
"total": "{Amount} + {Tax}",
"ratio": "({A} - {B}) / {C}",
"adjusted": "{Price} * 1.1",
"custom": "function:my_func",
}
特殊变量(Special Variables)
{_row_number}:模板内置的 **0-based 行号**(0, 1, 2, …),常用于生成序号/编号或做按行计算。需要从 1 开始的编号请写
{_row_number+1};与其他列组合(推荐显式
str()):例如"{bore_id} + '-' + str({_row_number+1})";补零(不要使用
"{...:03d}"这类格式化大括号):例如"'BH' + str({_row_number+1}).zfill(3)"生成BH001/BH002/...。纯数值列也可直接使用:例如
"{_row_number}"或"{_row_number*10}";与其他数值列联合计算:例如
"{base_value} + {_row_number}"。
from gdisdk.dataclass.tables import TableData
from gdisdk.modules.operators import AddTableColumns
table = TableData({
"bore_id": ["A", "B", "C"],
"base_value": [100, 200, 300],
})
add_cols = AddTableColumns("AddCols")
add_cols.InputTable = table
add_cols.column_names = [
{"name": "joint_number", "title": "接头编号"},
{"name": "bh_no", "title": "孔号(补零)"},
{"name": "serial_num", "title": "组合编号"},
{"name": "row_index", "title": "行号"},
{"name": "row_x10", "title": "行号乘 10"},
{"name": "adjusted_value", "title": "按行调整后的值"},
]
add_cols.column_templates = {
"joint_number": "'L' + str({_row_number+1})", # L1, L2, L3, ...
"bh_no": "'BH' + str({_row_number+1}).zfill(3)", # BH001, BH002, BH003, ...
"serial_num": "{bore_id} + '-' + str({_row_number+1})", # A-1, B-2, C-3
"row_index": "{_row_number}", # 0, 1, 2
"row_x10": "{_row_number*10}", # 0, 10, 20
"adjusted_value": "{base_value} + {_row_number}", # 100, 201, 302
}
out = add_cols.execute()
Note
AddTableColumns主要用于 按行 生成新列(row-level)。如果你要做聚合(如 sum/mean/count),更推荐使用TableCalculator。当模板用于字符串拼接时,引用到的列值若为
None/NaN会按空字符串处理;如果出现字符串与数字拼接,请使用 ``str(…)``(或让表达式中包含字符串字面量以触发自动转换兜底)。
内置 diff 函数(逐行差分)
模板中支持内置的 diff(col, group_col) 函数,无需写本地函数,适用于层厚、步长差值等需要”按组逐行差分”的场景。
语法:
{diff(col_name)}— 对整张表按 原始行顺序 做差分;{diff(col_name, group_col)}— 按group_col分组,在每组内按 原始行顺序 做差分。
行为说明:
diff 按输入数据的 原始行顺序 计算,不会自动排序。如果需要特定顺序(例如按深度升序计算层厚),请在传入
AddTableColumns前先使用相关模块排序;每组第一行(无前驱):差值 =
col_name本身(即默认顶面深度为 0);diff也可嵌套在更大的模板表达式中,如{diff(depth, bore_number)} * 1000。
from gdisdk.dataclass.tables import TableData
from gdisdk.modules.operators import AddTableColumns
# 勘探孔分层表,两个钻孔,数据已按钻孔编号和层底深度排序
table = TableData({
"bore_number": ["BH1", "BH1", "BH1", "BH2", "BH2"],
"layer_bottom_depth": [ 2.0, 5.0, 15.0, 3.0, 10.0],
})
add_cols = AddTableColumns("AddLayerThickness")
add_cols.InputTable = table
add_cols.column_names = [
{"name": "layer_thickness", "title": "地层厚度", "unit": "m"},
]
add_cols.column_templates = {
# 按钻孔编号分组,对层底深度做差分
"layer_thickness": "{diff(layer_bottom_depth, bore_number)}",
}
out = add_cols.execute()
# 输出(保持原始行顺序):
# BH1 分层 2→5→15 m → 厚度 2, 3, 10 m
# BH2 分层 3→10 m → 厚度 3, 7 m
#
# 注意:若数据未预先排序,请在上游先使用 SortTable 模块,
# 否则差分结果可能不正确。
本地函数(local function)示例与要求
1)Inline 方式(推荐,最方便)
from gdisdk.dataclass.tables import TableData
from gdisdk.modules.operators import AddTableColumns
def calculate_total(module, table, **kwargs):
# 约定签名:必须是 (module, table, **kwargs)
return table["Amount"] + table["Tax"]
table = TableData({"Amount": [10, 20], "Tax": [1, 2]})
add_cols = AddTableColumns(
column_names=[{"name": "total", "title": "总额"}],
column_templates={"total": "function:calculate_total"},
local_functions={"calculate_total": calculate_total},
)
add_cols.InputTable = table
out = add_cols.execute()
2)文件方式(上传GDIM必须采用此方式,需要 @local_function)
my_functions.py:
from gdisdk.pipeline.nameSpace import local_function
@local_function
def calculate_total(module, table, **kwargs):
return table["Amount"] + table["Tax"]
使用该文件中的函数:
from gdisdk.modules.operators import AddTableColumns
add_cols = AddTableColumns(
column_names=[{"name": "total", "title": "总额"}],
column_templates={"total": "function:calculate_total"},
local_functions_path="./my_functions.py",
)
Note
函数签名要求:自定义函数必须接受
(module, table, **kwargs)。优先级: - 若同时提供
local_functions(inline)与local_functions_path(文件),inline 优先; - 若 pipeline 设置了pipeline.local_functions_path,则会覆盖模块的local_functions_path。
参数说明
参数名 |
类型 |
默认值 |
说明 |
|---|---|---|---|
|
|
|
要新增/更新的列元数据列表;每个 dict 至少包含 |
|
|
|
列模板表达式(key 为列名)。使用 Python 表达式(逐行求值):支持 |
|
|
|
列静态值(单值广播或数组按行写入)。注意:若同列同时存在模板与静态值,模板优先。 |
|
|
|
本地函数脚本路径;若 pipeline 设置了 |
|
|
|
Inline 本地函数(key 为函数名,value 为可调用对象)。用于 |
|
|
|
仅用于本地函数加载/执行的调试输出。 |
Note
若模板表达式求值失败,该列会回退为
NaN,并给出warnings.warn提示。
上传 GDIM 前检查
是否需要特别处理:仅当
column_templates中使用了function:xxx本地函数时,是。必须检查:
上传前不要只依赖
local_functions={...}这类 inline 函数配置;改用
local_functions_path或pipeline.local_functions_path指向独立脚本文件,并在脚本中使用@local_function定义函数;若同时配置了
local_functions与local_functions_path,需注意 inline 优先,上传前应移除会遮蔽文件方式的 inline 配置。
建议检查:
自定义函数签名保持为
(module, table, **kwargs);本地函数脚本路径应优先在 pipeline 层 提供;上传平台后通常由平台注入或替换,而不是依赖写死在
.pipe中的本机路径。
若遗漏,常见现象:
本地执行
function:xxx正常,但保存为.pipe上传后,GDIM 无法还原 inline 函数对象,导致列模板计算失败。
在 pipeline 中的使用方式
from gdisdk.pipeline.pipeline import PipeLine
from gdisdk.modules.readers import CsvReader
from gdisdk.modules.operators import AddTableColumns
pipe = PipeLine(app_name="AddColsDemo", app_title="新增表格列示例")
read_csv = CsvReader("Read")
read_csv.file = "example.csv"
read_csv.encoding = "auto"
add_cols = AddTableColumns("AddCols")
add_cols.column_names = [{"name": "total", "title": "总额"}]
add_cols.column_templates = {"total": "{Amount} + {Tax}"}
links = read_csv.OutputTable >> add_cols.InputTable
pipe.add_links(links)
pipe.run()
out_table = add_cols.OutputTable.data
更多信息
TableCalculator
模块简介与适用场景
TableCalculator用于从输入表格生成 “计算/汇总后的新表格” ,支持两类模式:模板表达式支持聚合函数(示例:
{sum(Amount)}、{mean(Price)}、{count(*)}),并支持function:函数名的本地函数调用。
端口说明
输入端口 -
InputTable:输入表格(TableData)输出端口 -
OutputTable:输出表格(计算/汇总后的TableData)
快速上手示例 1:全表汇总(单行输出)
from gdisdk.dataclass.tables import TableData
from gdisdk.modules.operators import TableCalculator
table = TableData({"Amount": [10, 20, 30], "Tax": [1, 2, 3]})
calc = TableCalculator("Calc")
calc.InputTable = table
calc.column_names = [{"name": "grand_total", "title": "总计"}]
calc.column_templates = {"grand_total": "{sum(Amount)} + {sum(Tax)}"}
out = calc.execute()
print(out.dataframe)
快速上手示例 2:分组汇总(每组一行)
from gdisdk.dataclass.tables import TableData
from gdisdk.modules.operators import TableCalculator
table = TableData(
{"Category": ["A", "A", "B"], "Amount": [10, 20, 30]}
)
calc = TableCalculator("Calc")
calc.InputTable = table
calc.group_by = ["Category"]
calc.column_names = [
{"name": "total_amount", "title": "组内总量"},
{"name": "count", "title": "组内条数"},
]
calc.column_templates = {
"total_amount": "{sum(Amount)}",
"count": "{count(*)}",
}
out = calc.execute()
常见模板写法速查(聚合/汇总)
# 常见聚合函数(可直接用于 TableCalculator 的模板):
# - {sum(col)} / {mean(col)} / {min(col)} / {max(col)}
# - {count(*)} 统计行数;{count(col)} 统计该列长度
column_templates = {
"sum_amount": "{sum(Amount)}",
"avg_price": "{mean(Price)}",
"row_count": "{count(*)}",
"ratio": "{sum(A)} / {sum(B)} * 100",
}
本地函数(local function)示例与要求
1)Inline 方式:自定义汇总逻辑
from gdisdk.dataclass.tables import TableData
from gdisdk.modules.operators import TableCalculator
def weighted_average(module, table, **kwargs):
# table 可能是“全表”或“分组后的子表”(group_by 模式下)
w = table["weight"]
v = table["value"]
if float(w.sum()) == 0:
return 0.0
return float((v * w).sum() / w.sum())
table = TableData(
{"category": ["A", "A", "B"], "value": [10, 20, 30], "weight": [1, 2, 3]}
)
calc = TableCalculator(
group_by=["category"],
column_names=[{"name": "wavg", "title": "加权平均"}],
column_templates={"wavg": "function:weighted_average"},
local_functions={"weighted_average": weighted_average},
)
calc.InputTable = table
out = calc.execute()
2)文件方式:上传GDIM必须采用此方式(需要 @local_function)
aggregation_functions.py:
from gdisdk.pipeline.nameSpace import local_function
@local_function
def weighted_average(module, table, **kwargs):
w = table["weight"]
v = table["value"]
if float(w.sum()) == 0:
return 0.0
return float((v * w).sum() / w.sum())
使用:
from gdisdk.modules.operators import TableCalculator
calc = TableCalculator(
group_by=["category"],
column_names=[{"name": "wavg", "title": "加权平均"}],
column_templates={"wavg": "function:weighted_average"},
local_functions_path="./aggregation_functions.py",
)
Note
函数签名要求:自定义函数必须接受
(module, table, **kwargs),并返回标量或可写入表格的结果。优先级: - 若同时提供
local_functions(inline)与local_functions_path(文件),inline 优先; - 若 pipeline 设置了pipeline.local_functions_path,则会覆盖模块的local_functions_path。
参数说明
参数名 |
类型 |
默认值 |
说明 |
|---|---|---|---|
|
|
|
分组字段列表(可写字段 name 或 title,系统会尝试自动解析)。 |
|
|
|
输出表要生成的列元数据列表。 |
|
|
|
列模板表达式(支持聚合函数与算术表达式)。 |
|
|
|
是否在输出表中包含源表字段。分组模式下会对源字段取组内 “首值” 作为代表值。 |
|
|
|
输出表的 metadata(如 |
|
|
|
本地函数脚本路径(pipeline 优先)。 |
|
|
|
Inline 本地函数(key 为函数名,value 为可调用对象)。用于 |
|
|
|
本地函数加载/执行调试。 |
Note
当
group_by为空时,模板既可以写聚合(返回标量),也可以写行级表达式(返回序列);模块会自动把标量包装成单行表。
上传 GDIM 前检查
是否需要特别处理:仅当
column_templates中使用了function:xxx本地函数时,是。必须检查:
上传前不要只依赖
local_functions={...}这类 inline 函数配置;改用
local_functions_path或pipeline.local_functions_path指向独立脚本文件,并在脚本中使用@local_function定义函数;若同时配置了
local_functions与local_functions_path,需注意 inline 优先,上传前应移除会遮蔽文件方式的 inline 配置。
建议检查:
自定义函数签名保持为
(module, table, **kwargs),并返回可写入表格的标量或序列;本地函数脚本路径应优先在 pipeline 层 提供;上传平台后通常由平台注入或替换,而不是依赖写死在
.pipe中的本机路径。
若遗漏,常见现象:
本地执行
function:xxx正常,但保存为.pipe上传后,GDIM 无法还原 inline 函数对象,导致聚合列计算失败。
在 pipeline 中的使用方式
from gdisdk.pipeline.pipeline import PipeLine
from gdisdk.modules.readers import CsvReader
from gdisdk.modules.operators import TableCalculator
pipe = PipeLine(app_name="TableCalcDemo", app_title="表格汇总示例")
read_csv = CsvReader("Read")
read_csv.file = "example.csv"
read_csv.encoding = "auto"
calc = TableCalculator("Calc")
calc.group_by = ["Category"]
calc.column_names = [{"name": "total", "title": "组内总计"}]
calc.column_templates = {"total": "{sum(Amount)}"}
links = read_csv.OutputTable >> calc.InputTable
pipe.add_links(links)
pipe.run()
out_table = calc.OutputTable.data
更多信息
RenameTableColumns
模块简介与适用场景
RenameTableColumns用于重命名表格列,同时会同步更新字段元数据(fields_meta)以及 title/name 的映射关系。支持两种重命名模式:
rename_type="name":重命名列名(DataFrame 的 columns);rename_type="title":重命名字段标题(FieldMetadata.title)。
典型适用场景:
将外部数据的 “列名” 映射到系统规范字段名;
调整输出表的中文字段标题以符合报告/导出要求。
端口说明
输入端口 -
InputTable:输入表格(TableData)输出端口 -
OutputTable:重命名后的表格(TableData,并同步更新字段元数据与 title/name 映射)
快速上手示例 1:重命名列名
from gdisdk.dataclass.tables import TableData
from gdisdk.modules.operators import RenameTableColumns
table = TableData({"old": [1, 2, 3]}, name="demo", title="示例表")
ren = RenameTableColumns("Rename")
ren.InputTable = table
ren.rename_type = "name"
ren.column_name_map = {"old": "new"}
out = ren.execute()
快速上手示例 2:重命名字段标题
from gdisdk.dataclass.tables import TableData
from gdisdk.modules.operators import RenameTableColumns
table = TableData({"a": [1, 2, 3]})
# 假设该表已包含 fields_meta(例如来自 GDIM 或 update_fields_metadata 后)
ren = RenameTableColumns("Rename")
ren.InputTable = table
ren.rename_type = "title"
ren.column_name_map = {"旧标题": "新标题"}
out = ren.execute()
参数说明
参数名 |
类型 |
默认值 |
说明 |
|---|---|---|---|
|
|
|
选择重命名 “列名” 还是 “字段标题”。 |
|
|
|
映射关系;当 |
Note
若映射 key 在表中找不到,模块会跳过并给出
warnings.warn提示。
在 pipeline 中的使用方式
from gdisdk.pipeline.pipeline import PipeLine
from gdisdk.modules.readers import CsvReader
from gdisdk.modules.operators import RenameTableColumns
pipe = PipeLine(app_name="RenameColsDemo", app_title="重命名列示例")
read_csv = CsvReader("Read")
read_csv.file = "example.csv"
read_csv.encoding = "auto"
ren = RenameTableColumns("Rename")
ren.rename_type = "name"
ren.column_name_map = {"旧列名": "new_name"}
links = read_csv.OutputTable >> ren.InputTable
pipe.add_links(links)
pipe.run()
out_table = ren.OutputTable.data
更多信息