全部文档
文档中心财务模型deepcubepython组件deepcube模式使用手册

python组件deepcube模式使用手册

先胜云平台python组件中设有deepcube脚本模式,方便不熟悉python的用户更好地使用deepcube。本篇文档将介绍python-deepcube模式的使用方法,以及在python-deepcube模式与python-通用模式中使用deepcube的区别。

创建python元素时,用户可以选择DeepCubeScript模式。

在弹出框中选择要进行计算的财务模型(python-deepcube模式仅支持单cube内部计算,如果需要跨cube计算,可以使用python-通用模式使用原版deepcube进行计算)。

选择财务模型之后,需要配置数据加载范围。这里的数据加载范围是后续计算需要用到的所有来源数据的范围, 强烈建议配置cube中每个维度的范围,不要遗漏维度。 因为不配置的维度,默认都是取全部维度成员的数据,此处配置的范围越大,脚本计算时从财务模型取数的数据量就越多,因此在满足计算需要的前提下,将加载数据范围控制的越精确越好。

加载范围配置完成后,即可开始核心计算逻辑的编写。python-deepcube模式简化了deepcube语法,用户在使用源生deepcube时,需要先完成实例化DeepCube对象,定义维度变量,指定init和scope范围等一些列与计算逻辑无关的准备工作。而在python-deepcube模式中,用户只需专注于计算逻辑本身,例如下图展示了计算科目F_B60030103=F_B60030102+F_B60030101的写法:

python-deepcube模式之所以能达到用户操作简单的效果,背后的原因其实是python组件将用户的简化计算语句转换为了原始版本的deepcube语句,并在计算前后自动补充了数据加载,数据提交等步骤。点击脚本右上方的“打开代码预览”按钮,即可看到计算脚本最终转换为的python脚本,并能看到计算逻辑对应的代码块。

在源生deepcube中,用户需要导入deepcube包,创建财务模型和维度对象,而在python-deepcube模式中,这些操作都由系统自动生成,用户直接使用即可。 例如下图中,需要用到某个维度时,直接写对应的维度名即可,并且代码编辑器自带联想提示,方便用户输入。(需要提醒的是,因为财务模型设定上可以不同字段关联同一个维度,因此python-deepcube模式中所有提到的维度名实际是指财务模型字段名,例如财务模型实体维字段名为小写的entity,实际关联的维度名为大写的Entity,那么在python-deepcube模式中自动创建的实体维变量名为小写entity。)

维度成员的语法为:维度名[‘维度成员名’], 如果需要得到多个维度成员,语法为:维度名[‘维度成员名1’, ‘维度成员名2’…]

例如:

Copy
# 科目A
Account['A']

# 科目A,B,C
Account['A', 'B', 'C']

维度支持多种成员函数,包括获取某成员的子代,后代,先祖,父级,兄弟节点等,以下展示了成员函数的语法和含义:

Copy
# 获取Entity维度East成员的所有末级成员:
Base(Entity["East"])

# 获取Entity维度East成员自身及其全部末级成员:
IBase(Entity["East"])

# 获取Entity维度East成员的所有子级成员:
Children(Entity["East"])

# 获取Entity维度East成员自身及其全部子级成员:
IChildren(Entity["East"])

# 获取Entity维度East成员的所有后代成员:
Descendant(Entity["East"])

# 获取Entity维度East成员自身及其全部后代成员:
IDescendant(Entity["East"])

# 获取指定成员一定层级范围内的成员,下例为获取Entity维度East成员往上两层到往下三层的成员:
Level(Entity["East"], -2, 3)

# 获取Entity维度East成员的父级成员:
Parent(Entity["East"])

# 获取Entity维度East的所有先祖成员:
Ancestor(Entity["East"])

# 获取Year维度2024年的上一年,-1表示向前偏移1个成员,向后偏移可传入正数:
Shift(Year["2024"], -1)

维度成员集合支持根据维度属性过滤成员范围,并且支持多过滤条件组合使用:

Copy
# 获取Entity维度East成员的所有末级成员中,ud1是"SH"的成员:
Base(Entity["East"], Attr("ud1")=="SH")
# 获取Entity维度East成员的所有末级成员中,ud1不是"SH",并且ud2是"T1"或"T2"的成员:
Base(Entity["East"], (Attr("ud1")!="SH") & (Attr("ud2").isin(["T1", "T2"])))
# 获取Entity维度East成员的所有末级成员中,ud1是"SH"并且ud2是"T1",或者ud1是"HZ"并且ud2是"T2"的成员:
Base(Entity["East"], ((Attr("ud1")=="SH") & (Attr("ud2")=="T1")) | ((Attr("ud1")=="HZ") & (Attr("ud2")=="T2")))

维度成员集合之间可以进行并集(+),差集(-),交集(&)的处理。

Copy
# 以下两个成员集合相加,取并集,得到一个新的成员集合,其成员包括 [Q1,1,2,3,4,5,6]
IBase(period['Q1']) + Base(period['Q2'])

# 以下两个成员集合相减,取差集,得到一个新的成员集合,其成员包括 [Hy1,Q1,Q2,1,2,3]
IDescendant(period['Hy1']) - Base(period['Q2'])

# 以下两个成员集合取交集,得到一个新的成员集合对象,其成员包括 [2,4,6]
IDescendant(period['Hy1']) & period['2','4','6','8']

# +,-,&可以组合使用,以下结果集成员包括 [Q1,2,3,Q2]
period['Q1'].IBase() + period['Q2'] - period['1']

# &的优先级高于+和-,必要时可以使用小括号,以下结果集成员包括 [2,Q2]
(period['Q1'].IBase() + period['Q2']) & period['2','Q2','Hy2']

在源生deepcube中,用户需要使用cube对象的loc函数来进行计算(写法如:main_cube.loc[xxx]),在python-deepcube模式中,系统对财务模型对象进行了封装,所有的计算统一使用BLOCK关键字(意为数据块),BLOCK关键字后需要使用中括号[],中括号内可以填入一个或多个维度的成员或成员集合。数据块之间可以进行四则运算,并且将计算结果赋值给另一个数据块。

例如下例展示了科目A等于科目B加上Scenario为Actual的科目C的计算写法:

Copy
BLOCK[Account['A']] = BLOCK[Account['B']] + BLOCK[Account['C'], Scenario['Actual']]

在源生deepcube中,用户需要使用cube对象的scope函数来进行计算(写法如:main_cube.scope(xxxx)),在python-deepcube模式中,scope定义使用SCOPE关键字,并且默认SCOPE范围为配置的数据加载范围。 数据块计算范围最终是BLOCK与SCOPE联合决定的,同一个维度如果BLOCK中有指定,以BLOCK为准,如果没有指定,以SCOPE为准。

用户可以随时重新指定SCOPE,SCOPE中声明的维度的范围将改变,其他没有声明的维度仍延续之前的SCOPE设定。

值得一提的是,BLOCK中可以指定多个维度,也可以指定成员集合。 并且来源集(等号右边的数据块)中未指定的维度以目标集(等号左边的数据块)为准。

条件判断分为两种,一种是按照维度成员不同进行不同的计算规则,另一种是按照度量值不同进行不同的计算规则。

对于第一种按照维度成员的条件判断,在deepcube中无需使用额外语法,可以直接拆分为两个数据块进行计算。 例如我们有需求,要计算Entity维度东区的所有末级组织,当组织ud1为type1时,计算科目A=科目B+科目C,当组织ud1为type2时,计算科目A=科目B+科目D。

Copy
# 要计算Entity维度东区的所有末级组织,当组织ud1为type1时,计算科目A=科目B+科目C,当组织ud1为type2时,计算科目A=科目B+科目D
BLOCK[Account['A'], Base(Entity['East'], Attr('ud1')=='type1')] = BLOCK[Account['B']] + BLOCK[Account['C']]
BLOCK[Account['A'], Base(Entity['East'], Attr('ud1')=='type2')] = BLOCK[Account['B']] + BLOCK[Account['D']]

对于第二种按照度量值进行条件判断,需要使用IIF函数。IIF语法如下,如果condition判断条件为True,则执行formula1,否则执行formula2: IIF(condition,formula1,formula2) condition:判断条件,必传。 判断条件中的数据块关键字使用BLOCK_VAL formula1:计算表达式1 formula2:计算表达式2

Copy
# 当科目'flag'的值为'规则1'时,计算科目A=科目B*科目C,否则计算科目A=科目B*科目D
BLOCK[Account['A']] = IIF(BLOCK_VAL[Account['flag']] == '规则1', BLOCK[Account['B']] * BLOCK[Account['C']], BLOCK[Account['B']] * BLOCK[Account['D']])
# IIF函数支持多层嵌套,例如当科目B<0时,计算科目A=-科目C * 科目D,科目B=0时,计算科目A=0,科目B>0时,计算科目A=科目C * 科目D:
BLOCK[Account['A']] = IIF(BLOCK_VAL[Account['B']] < 0,
    - BLOCK[Account['C']] * BLOCK[Account['D']] ,
    IIF(BLOCK_VAL[Account['B']] == 0, 0, BLOCK[Account['C']] * BLOCK[Account['D']]))

清数使用CLEAR_DATA函数。CLEAR_DATA中每个维度只能出现一次,未指定的维度以SCOPE中对应维度范围为准。 需要注意的是,清数只能清除加载范围或计算结果范围内的数据。

Copy
# 清除2024年,1~12月,科目A的数据
CLEAR_DATA(Account['A'], Year['2024'], Base(Period['TotalPeriod']))

有些需求场景会需要在计算中跨维度置换成员,此时可以使用CROSS_DIMENSION函数: CROSS_DIMENSION(data_block,cross_dim) data_block:BLOCK数据块,必传 cross_dim:需要跨维度计算的维度 CROSS_DIMENSION函数需要与cube计算配套使用,出现在等号右边

例如在关联方交易计算中,我们需要将一部分数据的entity和partner成员互换,然后再进行计算。

Copy
# 计算partner所有base成员的A0102科目,等于A010101科目乘以A010103科目,但是A010103科目的数据块entity和partner维度互换
BLOCK[account["A0102"],partner['total'].Base()] = BLOCK[account["A010101"]] * CROSS_DIMENSION(BLOCK[
    account["A010103"],entity['total'].Base()], {"entity":"partner"})

deepcube支持的聚合函数包括求和SUM,求平均值AVG,求最大值MAX,求最小值MIN。数学函数包括求绝对值ABS,四舍五入ROUND。 具体语法示例如下:

Copy
# 计算2024年的Beginning数据等于2023年1~12月+Beginning的合计值。
SCOPE(Base(Entity["East"]), Year['2024'])
BLOCK[period["Beginning"]] = SUM(BLOCK[period["TotalPeriod"].Base()+period["Beginning"], year['2023']])

# 计算2025年1月数据等于2024年1~12月的平均值。
BLOCK[Year['2025'], period["1"]] = AVG(BLOCK[period["TotalPeriod"].Base(), year['2024']])

# 计算2025年1月数据等于2024年1~12月的最大值。
BLOCK[Year['2025'], period["1"]] = MAX(BLOCK[period["TotalPeriod"].Base(), year['2024']])

# 计算2025年1月数据等于2024年1~12月的最小值。
BLOCK[Year['2025'], period["1"]] = MIN(BLOCK[period["TotalPeriod"].Base(), year['2024']])

# 计算Account A1的值等于A2值的绝对值
BLOCK[Account['A1']] = ABS(BLOCK[Account['A2']])

# 在计算中保留2位小数。
BLOCK[Account['A']] = ROUND(BLOCK[Account['B']] * BLOCK[Account['C'], Period['NoPeriod']], 2)

在使用deepcube编写完逻辑之后,通常需要进行调试,在调试时,可以使用DISPLAY_DATA对数据进行打印,从而看到计算的结果,或者打印来源集数据块来检查数据是否正常加载。DISPLAY_DATA语法如下: DISPLAY_DATA(data_block, max_rows, max_cols, sort_by) data_block:BLOCK数据块,必传 max_rows:打印的最大行数,选传,默认100行 max_cols:打印的最大列数,选传 sort_by:按照指定字段排序,选传

需要注意的是DISPLAY_DATA中需要传入一个BLOCK数据块来表示打印的数据块范围,BLOCK数据块中未指定的维度会以SCOPE为准。并且如果指定的数据范围包括了父级节点,DISPLAY_DATA的打印是包含动态汇总的父级节点的。

回到顶部

咨询热线

400-821-9199

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

ctrl+Enter to send