code: def decompose_portofolio(
      stock_weight_df, stock_group_df, stock_ret_df
  ):
      """
      :param stock_weight_df: a pandas dataframe to describe the portofolio by weight.
                      every row corresponds to a  day
                      every column corresponds to a stock.
                      Here is an example below.
                      code        SH600004  SH600006  SH600017  SH600022  SH600026  SH600037  \
                      date
                      2016-01-05  0.001543  0.001570  0.002732  0.001320  0.003000       NaN
                      2016-01-06  0.001538  0.001569  0.002770  0.001417  0.002945       NaN
                      2016-01-07  0.001555  0.001546  0.002772  0.001393  0.002904       NaN
                      2016-01-08  0.001564  0.001527  0.002791  0.001506  0.002948       NaN
                      2016-01-11  0.001597  0.001476  0.002738  0.001493  0.003043       NaN
                      ....
  
      :param stock_group_df: a pandas dataframe to describe  the stock group.
                      every row corresponds to a  day
                      every column corresponds to a stock.
                      the value in the cell repreponds the group id.
                      Here is a example by for stock_group_df for industry. The value is the industry code
                      instrument  SH600000  SH600004  SH600005  SH600006  SH600007  SH600008  \
                      datetime
                      2016-01-05  801780.0  801170.0  801040.0  801880.0  801180.0  801160.0
                      2016-01-06  801780.0  801170.0  801040.0  801880.0  801180.0  801160.0
                      2016-01-07  801780.0  801170.0  801040.0  801880.0  801180.0  801160.0
                      2016-01-08  801780.0  801170.0  801040.0  801880.0  801180.0  801160.0
                      2016-01-11  801780.0  801170.0  801040.0  801880.0  801180.0  801160.0
                      ...
  
      :param stock_ret_df:   a pandas dataframe to describe the stock return.
                      every row corresponds to a day
                      every column corresponds to a stock.
                      the value in the cell repreponds the return of the group.
                      Here is a example by for stock_ret_df.
                      instrument  SH600000  SH600004  SH600005  SH600006  SH600007  SH600008  \
                      datetime
                      2016-01-05  0.007795  0.022070  0.099099  0.024707  0.009473  0.016216
                      2016-01-06 -0.032597 -0.075205 -0.098361 -0.098985 -0.099707 -0.098936
                      2016-01-07 -0.001142  0.022544  0.100000  0.004225  0.000651  0.047226
                      2016-01-08 -0.025157 -0.047244 -0.038567 -0.098177 -0.099609 -0.074408
                      2016-01-11  0.023460  0.004959 -0.034384  0.018663  0.014461  0.010962
                      ...
  
      :return: It will decompose the portofolio to the group weight and group return.
      """
      all_group = np.unique(stock_group_df.values.flatten())
      all_group = all_group[~np.isnan(all_group)]
  
      group_weight, stock_weight_in_group = decompose_portofolio_weight(
          stock_weight_df, stock_group_df
      )
  
      group_ret = {}
      for group_key, val in stock_weight_in_group.items():
          stock_weight_in_group_start_date = min(val.index)
          stock_weight_in_group_end_date = max(val.index)
  
          temp_stock_ret_df = stock_ret_df[
              (stock_ret_df.index >= stock_weight_in_group_start_date)
              & (stock_ret_df.index <= stock_weight_in_group_end_date)
          ]
  
          group_ret[group_key] = (temp_stock_ret_df * val).sum(axis=1)
          # If no weight is assigned, then the return of group will be np.nan
          group_ret[group_key][group_weight[group_key] == 0.0] = np.nan
  
      group_weight_df = pd.DataFrame(group_weight)
      group_ret_df = pd.DataFrame(group_ret)
      return group_weight_df, group_ret_df
  
file_path: qlib/qlib/backtest/profit_attribution.py
imports: import datetime
  from pathlib import Path
  import numpy
  import pandas
  from ..config import C
  from ..data import D
  from .position import Position
label_desc: Use image node_id 4 for calling a global function with example usage: decompose_portofolio(stock_weight_df, stock_group_df, stock_ret_df) and returns: group_weight_df,  group_ret_df