使用两个索引访问 pyomo 变量

Accessing pyomo variables with two indices

我已经开始使用 pyomo 来解决优化问题。关于访问使用两个索引的变量,我有一点问题。我可以轻松打印解决方案,但我想将取决于变量值的索引存储在 pd.DataFrame 中以进一步分析结果。我写了下面的代码,但它需要永远存储变量。有没有更快的方法?

df_results = pd.DataFrame()
df_variables = pd.DataFrame()

results.write()
instance.solutions.load_from(results)

for v in instance.component_objects(Var, active=True):
    print ("Variable",v)
    varobject = getattr(instance, str(v))

    frequency = np.empty([len(price_dict)])

    for index in varobject:
        exist = False
        two = False
        if index is not None:
            if type(index) is int:
                #For time index t (0:8760 hours of year)
                exists = True #does a index exist
                frequency[index] = float(varobject[index].value)
            else:
                #For components (names)
                if type(index) is str:
                    print(index)
                    print(varobject[index].value)
                else:
                    #for all index with two indices
                    two = True #is index of two indices
                    if index[1] in df_variables.columns:
                        df_variables[index[0], str(index[1]) + '_' + str(v)] = varobject[index].value
                    else:
                        df_variables[index[1]] = np.nan
                        df_variables[index[0], str(index[1]) + '_' + str(v)] = varobject[index].value

        else:
            # If no index exist, simple print the variable value
            print(varobject.value)

        if not(exists):
            if not(two):
                df_variable = pd.Series(frequency, name=str(v))
                df_results = pd.concat([df_results, df_variable], axis=1)
                df_variable.drop(df_variable.index, inplace=True)
            else:
                df_results = pd.concat([df_results, df_variable], axis=1)
                df_variable.drop(df_variable.index, inplace=True)

通过更多的工作和更少的 DataFrame,我已经用下面的代码解决了这个问题。感谢 BlackBear 的评论

    df_results = pd.DataFrame()
    df_variables = pd.DataFrame()

    results.write()
    instance.solutions.load_from(results)

    for v in instance.component_objects(Var, active=True):
        print ("Variable",v)
        varobject = getattr(instance, str(v))

        frequency = np.empty([20,len(price_dict)])

        exist = False
        two = False

        list_index = []
        dict_position = {}
        count = 0

        for index in varobject:
            if index is not None:
                if type(index) is int:
                    #For time index t (0:8760 hours of year)
                    exist = True #does a index exist
                    frequency[0,index] = float(varobject[index].value)
                else:
                    #For components (names)
                    if type(index) is str:
                        print(index)
                        print(varobject[index].value)
                    else:
                        #for all index with two indices
                        exist = True
                        two = True #is index of two indices
                        if index[1] in list_index:
                            position = dict_position[index[1]]
                            frequency[position,index[0]] = varobject[index].value
                        else:
                            dict_position[index[1]] = count
                            list_index.append(index[1])
                            print(list_index)
                            frequency[count,index[0]] = varobject[index].value
                            count += 1
            else:
                # If no index exist, simple print the variable value
                print(varobject.value)

        if exist:
            if not(two):
                frequency = np.transpose(frequency)
                df_variable = pd.Series(frequency[:,0], name=str(v))
                df_results = pd.concat([df_results, df_variable], axis=1)
                df_variable.drop(df_variable.index, inplace=True)
            else:
                for i in range(count):
                    df_variable = pd.Series(frequency[i,:], name=str(v)+ '_' + list_index[i])
                    df_results = pd.concat([df_results, df_variable], axis=1)
                    df_variable.drop(df_variable.index, inplace=True)