sql 计算字段相加_一半是海水,一半是火焰:公式计算时的行计算与列计算

5deba2dd003a61500c43b10c6bc39999.png
老王:二叉树非递归生成字符串​zhuanlan.zhihu.com
2f174429bb3d32a7b25bb281acc238f2.png

--这篇文章中的后序遍历二叉树,能解析公式定义,如果需要的话,可以把生成字符串的步骤,用加减乘除代替,直接得到计算结果。可是,一旦把left_number或者right_number换成KPI,在我们的业务框架里,就变成了借助pandas.DataFrame进行的列计算。

如何让行列计算兼容呢?

本来想找找Superset是否有代码可以参考,马上就想到,Superset自定义的metrics,公式是透传给数据库的,也就是说Superset没有这样的功能。

2019-08-05补充:

行列计算兼容是可行的,无论是两个df.column相加,还是两个df.column相加得到的结果,再与数字相加,结果都是pandas.core.series.Series对象,可以和原来的stack兼容。


能用变量去接受两个column相加的结果,再push到stack么?

tmp = DataFrame['column_name_1'] + DataFrame['column_name_2']

value_list.append(tmp)


2019-08-05

准备工作

  • 结果集要放到postorderTraversal函数能访问到的地方

--给postorderTraversal增加参数,传递dataframe list的字典,key:dataset_id

  • 如何判断某个kpi的名字在DataFrame中是否存在

--https://stackoverflow.com/questions/24870306/how-to-check-if-a-column-exists-in-pandas

--一列:可以用if 'A' in df.columns:

--多列:用if set(['A', 'C']).issubset(df.columns):

  • 从业务逻辑上说,postorderTraversal这个名字离底层实现近,离业务逻辑远,不如把两个函数放到一个类里面,结果集可以当成__init__函数的入参。

--参考:https://stackoverflow.com/questions/9056957/correct-way-to-define-class-variables-in-python

Elements outside the __init__ method are static elements; they belong to the class.
Elements inside the __init__ method are elements of the object ( self); they don't belong to the class.
  • 重新构建dataframe构成的结果集

--原来是用的list,现在要改成dict

--原来的逻辑:遍历kpi构成的树(formula节点的类型为kpi),得到一个公式用到的kpi的全集,再用DataFrame的group_by函数,将kpi按其所属的dataset分类。

--然后,遍历分组,对每一组kpi,构建sql语句,查询数据,放入DataFrame中。

--需要改造的点:用dataset_id和查询所得的df,拼装成一个字典元素。

            for name, group in grouped_kpi:
                single_superset_datasource = self.get_superset_datasource(name)
                ...
                sql = single_superset_datasource.get_query_str_from_name(group, 100)
                tmp_df = single_superset_datasource.query_by_simple_sql(sql)
                basic_df_dict.update({name: tmp_df})

输出:

2019-08-05 14:17:43,556:DEBUG:root:basic_df_dict:
2019-08-05 14:17:43,556:DEBUG:root:{520:      itemid
0   6536768
1   6535821
...
[100 rows x 1 columns], 521:            value
0   0.000000e+00
1   3.000000e+01

对两个df的column相加:

                        if left_kpi.name in left_df.columns and right_kpi.name in right_df.columns:
                            value = left_df[left_kpi.name] + right_df[right_kpi.name]
                            logging.debug('type of df.column + df.column:')
                            logging.debug(type(value))

输出:

2019-08-05 15:06:40,126:DEBUG:root:type of df.column + df.column:
2019-08-05 15:06:40,127:DEBUG:root:<class 'pandas.core.series.Series'>

可以看到,两个df.column相加得到Series对象。

那么,Series对象再与数字相加,还会生成Series对象么?

继续加日志,可以看到,数字和Series对象相加,仍然是Series对象:

2019-08-05 15:29:30,655:DEBUG:root:type of middle_value:
2019-08-05 15:29:30,655:DEBUG:root:<class 'pandas.core.series.Series'>

所以,把pandas.DataFrame.column放到公式中是可行的,在遇到df.column之后,value从原来的数字,变成一个Series对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值