将输出变量拆分为大小相似的数据帧并合并它们

Split output variable into similarly sized dataframes and merge those

我的问题:试图将一个输出变量拆分成类似大小的数据帧并合并它们

模型输出:"var"

{('Product1', 0): <gurobi.Var listing[Product1,0] (value 1.0)>, ('Product1', 1): <gurobi.Var listing[Product1,1] (value 0.0)>, ('Product1', 2): <gurobi.Var listing[Product1,2] (value 0.0)>, ('Product1', 3): <gurobi.Var listing[Product1,3] (value 0.0)>, ('Product2', 0): <gurobi.Var listing[Product2,0] (value 1.0)>, ('Product2', 1): <gurobi.Var listing[Product2,1] (value 0.0)>, ('Product2', 2): <gurobi.Var listing[Product2,2] (value 0.0)>, ('Product2', 3): <gurobi.Var listing[Product2,3] (value 0.0)>, ('Product3', 0): <gurobi.Var listing[Product3,0] (value 1.0)>, ('Product3', 1): <gurobi.Var listing[Product3,1] (value 0.0)>, ('Product3', 2): <gurobi.Var listing[Product3,2] (value 0.0)>, ('Product3', 3): <gurobi.Var listing[Product3,3] (value 0.0)>}
<class 'gurobipy.tupledict'>

期望的输出: 所需的输出应如下所示:

                    0    1    2    3                                
Product1          1.0  0.0  0.0  0.0
Product2          1.0  0.0  0.0  0.0
Product3          0.0  0.0  0.0  1.0
<class 'pandas.core.frame.DataFrame'>

我的(非常手动的)尝试:

1) 我把输出变量变成了一个dataframe "df_listing":

dict_listing = {k : v.X for k,v in var.items()}
df_listing = pd.DataFrame.from_dict(dict_listing, orient='index')
df_listing = df_listing.rename(columns = {0: 'listing'})

               listing
(Product1, 0)      1.0
(Product1, 1)      0.0
(Product1, 2)      0.0
(Product1, 3)      0.0
(Product2, 0)      1.0
(Product2, 1)      0.0
(Product2, 2)      0.0
(Product2, 3)      0.0
(Product3, 0)      0.0
(Product3, 1)      0.0
(Product3, 2)      0.0
(Product3, 3)      1.0
<class 'pandas.core.frame.DataFrame'>

2) 转置 "df_listing":

df_listing = df_listing.transpose()

3) 使用 k,它是列数 - 在本例中是 4 --> 0,1,2,3

df_Product1 = df_listing.iloc[:, 0*k:1*k]
df_Product1.columns = list(range(k))
df_Product2 = df_listing.iloc[:, 1*k:2*k]
df_Product2.columns = list(range(k))
df_Product3 = df_listing.iloc[:, 2*k:3*k]
df_Product3.columns = list(range(k))

4) 连接三个数据帧

input = [df_Product1, df_Product2, df_Product3]
df_facingsProductAll = pd.concat(input)

我的尝试是非常手动的,所以我正在寻找 a) 更 自动化的解决方案 ,可能使用 for 循环和 b) 更 动态代码,以便输入可以是更多产品,例如5 个产品,

感谢小伙伴们的帮助!

这是您的示例数据的简化版本:

import pandas as pd
df = pd.DataFrame({'product': [('Product 1' , 0), ('Product 1', 1) , ('Product 2', 0), ('Product 2', 1)],
                   'listing': [1.0, 0.0, 1.0, 0.0]})
df

然后重置索引列,将产品名称从 'index'

中拆分出来
df['prod_indx'] = df['product'].apply(lambda x: x[1])
df['product'] = df['product'].apply(lambda x: x[0])

然后旋转

output = pd.pivot_table(df, values='listing', columns='prod_indx', index='product', aggfunc=sum)
print(output)

你可以试试这个

import pandas as pd
from io import StringIO

txt = """
               listing
(Product1,0)      1.0
(Product1,1)      0.0
(Product1,2)      0.0
(Product1,3)      0.0
(Product2,0)      1.0
(Product2,1)      0.0
(Product2,2)      0.0
(Product2,3)      0.0
(Product3,0)      0.0
(Product3,1)      0.0
(Product3,2)      0.0
(Product3,3)      1.0"""

df = pd.read_csv(StringIO(txt), delim_whitespace=True)

df = df.reset_index()

# split index and concat to df

df = pd.concat([df,
                pd.DataFrame(df["index"].str.split(",")\
                                        .values.tolist(),
                             columns=["a","b"])],
                axis=1)

df = df.drop("index", axis=1)

# remove brackets
df["a"] = df["a"].str[1:]
df["b"] = df["b"].str[:-1].astype(int)

out = pd.pivot_table(df,
                     index="a",
                     columns="b",
                     values="listing")

输出

b           0    1    2    3
a                           
Product1  1.0  0.0  0.0  0.0
Product2  1.0  0.0  0.0  0.0
Product3  0.0  0.0  0.0  1.0

更新

如果您有空格 (Product1, 0) 您可以按以下步骤进行:

txt = """
               listing
(Product1, 0)      1.0
(Product1, 1)      0.0
(Product1, 2)      0.0
(Product1, 3)      0.0
(Product2, 0)      1.0
(Product2, 1)      0.0
(Product2, 2)      0.0
(Product2, 3)      0.0
(Product3, 0)      0.0
(Product3, 1)      0.0
(Product3, 2)      0.0
(Product3, 3)      1.0"""

df = pd.read_csv(StringIO(txt), delim_whitespace=True)

df = df.reset_index()\
       .rename(columns={"level_0":"a",
                        "level_1":"b"})
# remove brackets
df["a"] = df["a"].str[1:-1]
df["b"] = df["b"].str[:-1].astype(int)