如何让行列计算兼容呢?
本来想找找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对象。