财务模型

财务模型 (FinancialModel / CUB) 是 DeepFOS 平台的核心组件,用于存储和管理多维财务数据。

Copy
from deepfos.element.finmodel import FinancialCube

cube = FinancialCube('Ana_Cube')

根据维度表达式和 POV 查询财务模型数据。compact=True 时返回 (DataFrame, dict) 二元组,将公共维度放在 dict 中以减少数据冗余;compact=False 时返回单个 DataFrame,公共维度会复制到每一行。

Copy
data, return_pov = cube.query(
    "Year{2024}->Entity{firm1}",
    pov={"Scenario": "Actual"}
)

print(data.head())
print(return_pov)

若需要将某个维度成员展开为列(透视表格式),可使用 pivot_dim 参数:

Copy
# 将 Account 维度成员展开为列
data = cube.query(
    "Year{2024}->Entity{firm1}",
    pov={"Scenario": "Actual"},
    pivot_dim="Account",
    compact=False
)
# 此时 data 的列为:Year, Entity, Revenue, Cost, ...

适用于明细行格式的数据保存。DataFrame 中每一行都对应一个明确的维度组合,data 列为待写入数值;其余列需要提供参与保存的维度成员。

Copy
import pandas as pd

# 每一行需要包含 data 列以及参与保存的维度列

df = pd.DataFrame({
    "Year": ["2024", "2024"],
    "Entity": ["firm1", "firm2"],
    "Account": ["Revenue", "Revenue"],
    "Scenario": ["Actual", "Actual"],
    "data": [1000000, 2000000]
})

cube.save(df)

适用于透视表格式的数据保存。此时某一个维度的成员已经展开为多列,例如 20232024 这些年份列。save_unpivot() 会先把这些列还原为行,再按标准财务模型格式保存。

常见场景是先通过 query(..., pivot_dim="Year") 或在 Excel / pandas 中做透视分析,修改后再回写财务模型。

Copy
import pandas as pd

# 透视后的年份列将被还原为维度成员

df = pd.DataFrame({
    "Entity": ["firm1", "firm2"],
    "Account": ["Revenue", "Revenue"],
    "2023": [950000, 1800000],
    "2024": [1000000, 2000000]
})

cube.save_unpivot(df, unpivot_dim="Year", pov={"Scenario": "Budget"})

区别说明:save() 直接保存行式明细数据;save_unpivot() 用于把“成员在列上”的宽表数据还原后保存。若数据本身已经是一行一条记录的明细格式,使用 save() 即可。

适用于需要记录数据审计日志的删除场景。此方法会先查询出待删除数据,再将其值置为 null 后保存,因此会留下审计记录,但对大数据量可能有性能影响。

Copy
# 使用字典指定范围
cube.delete({
    "Year": ["2023", "2024"],
    "Entity": "firm1",
    "Scenario": "Budget"
})

# 或使用维度表达式
cube.delete("Year{2023;2024}->Entity{firm1}->Scenario{Budget}")

适用于 ClickHouse 事实表场景下的高效清数。此方法直接在数据库层面插入 null 记录,不经过查询步骤,性能更优,但不会记录到数据审计日志。

在 MySQL 事实表场景下,insert_null() 效果等同于 delete()

Copy
# 在 ClickHouse 事实表场景下,推荐使用 insert_null 清数
cube.insert_null("Year{2024}->Entity{firm1}->Scenario{Budget}")

区别说明:delete() 会先查询再置空,留下审计记录,适合需要追溯的场景;insert_null() 直接写入 null,性能更高,适合 ClickHouse 大批量清数场景。

用于在不同维度组合间复制数据,常见于跨期间、跨版本、跨主体的数据复制场景。formula 指定源和目标维度成员,fix_members 指定固定的维度范围。

Copy
cube.copy_calculate(
    formula="Account{Revenue_Copy}=Account{Revenue}",
    fix_members="Entity{firm1}->Year{2024}->Scenario{Actual}"
)

典型场景:

  • 将上期数据复制到本期作为初始值

  • 将实际数据复制到预算版本作为基准

  • 将某个主体的数据复制到另一个主体

用于启用审批流的财务模型,初始化审批单元状态表。process_map 定义流程控制维度(如年份),data_block_map 定义审批单元维度(如主体),status 为初始审批状态。

Copy
cube.pc_init(
    process_map={"Year": "Year{2024}"},
    data_block_map={"Entity": "Entity{firm1;firm2}"},
    status="1"
)

适用场景:在启用预算审批、数据锁定等权限控制功能时,需要先调用此方法初始化状态表。

用于更新指定审批单元的状态,例如从”编制中”更新为”已提交”或”已审批”。

Copy
cube.pc_upsert(
    process_map={"Year": "Year{2024}"},
    data_block_map={"Entity": "Entity{firm1}"},
    status="2"
)

适用场景:在审批流程中,根据业务逻辑更新审批单元状态,控制数据的可编辑性。

用于执行财务模型内的 MDX 计算脚本,适合批量计算派生指标、汇总值或按规则回写结果。parameters 可传入脚本中使用的参数,round_type 用于控制小数保留方式。

Copy
from deepfos.element.finmodel import RoundType

script = """
Scope([Scenario].[Actual], [Year].[2024], Base([Entity].[TotalEntity]));
[Account].[Total_Sales] = [Account].[Volume] * [Account].[Price];
End Scope;
"""

cube.mdx_execution(
    script=script,
    parameters={},
    round_type=RoundType.round
)

适用场景:

  • 批量执行财务模型计算规则

  • 生成汇总指标、派生指标

  • 在预算、预测、合并等场景中批量刷新计算结果


通过指定财务模型名称和路径,可以快速连接到目标财务模型。

Copy
from deepfos.element.finmodel import FinancialCube

cube = FinancialCube('Management_Report', entry_object='rate_exchange_calc')
Copy
cube = FinancialCube('CNcube_budget', path='/Application/01_CNHotel/03_CUB')

适用场景:

  • 普通预算/实际/汇率/分摊脚本

  • 在指定路径下访问某个财务模型

  • entry_object 标记写数来源

在批量查询场景下,通常会先构造维度条件,再通过 dict_to_expr() 生成表达式。

Copy
from deepfos.element.finmodel import FinancialCube
from deepfos.lib.utils import dict_to_expr

cube = FinancialCube('CNcube_budget', path='/Application/01_CNHotel/03_CUB')
fix = {
    'Year': '2024',
    'Scenario': 'Budget',
    'Entity': 'Base(#root,0)',
    'View': 'Periodic'
}

df = cube.query(expression=dict_to_expr(fix), compact=False)

适用场景:

  • 按 POV 条件读取预算/实际数据

  • 版本复制前取源数据

  • 汇率转换、YTD、分摊前取源切片

在重新写入数据前,可先按维度范围清空目标切片。

Copy
from deepfos.element.finmodel import FinancialCube
from deepfos.lib.utils import dict_to_expr

cube = FinancialCube('CNcube_budget', path='/Application/01_CNHotel/03_CUB')
fix = {
    'Year': '2024',
    'Scenario': 'Budget',
    'Entity': 'Base(E01,0)'
}
cube.delete(expression=dict_to_expr(fix))

适用场景:

  • 回写前先清空目标范围

  • 版本复制前清旧数据

  • 重新计算前重置切片

计算结果整理为标准明细结构后,可通过 save() 批量写回财务模型。

Copy
from deepfos.element.finmodel import FinancialCube

cube = FinancialCube('CNcube_budget', path='/Application/01_CNHotel/03_CUB')
cube.save(df_result, chunksize=20000)

适用场景:

  • 批量回写计算结果

  • 实际数装载

  • YTD/分摊/汇率计算结果落库

  • 财务模型的典型使用方式是先查询、再计算、最后保存结果。

  • 批量查询或清数时,通常会先构造 fix 字典,再通过 dict_to_expr() 生成表达式。

  • 在需要标记写数来源时,可在初始化 FinancialCube 时传入 entry_object

  • 大批量写入时,建议结合 chunksize 控制单次提交的数据量。


  1. 数据查询:对于开启了累计数自动计算的财务模型,数据查询时建议传入参数normalize_view=True以兼容历史版本的财务项目返参结果。

  2. 数据保存save() 适合行式明细数据;save_unpivot() 适合成员在列上的透视表数据,保存前会先还原为标准行式结构。

  3. 清数方式:在 ClickHouse 事实表场景下,推荐使用 insert_null();若需要保留数据审计记录,则应使用 delete()

  4. 数据复制copy_calculate() 适合做跨期间、跨版本、跨成员的数据复制,适合作为预算编制或预测初始化手段。

  5. 权限控制:预算开版,增加维度成员后初始化对应成员的权限状态等场景,建议使用 pc_upsert() 按审批流程更新状态。

  6. MDX 计算mdx_execution() 适合批量执行财务模型计算规则,用于刷新派生指标、汇总值或批量回写结果。

回到顶部

咨询热线

400-821-9199

我们使用 ChatGPT,基于文档中心的内容以及对话上下文回答您的问题。

ctrl+Enter to send