比pivot_table / groupby

问题描述

为了评估我的遗传算法,我必须执行大量迭代的计算。必须进行100到500次迭代,对于每次迭代,必须对100个人进行以下计算。我从使用groupby和list comprehension开始,但是这花了13秒钟,由于Faster way to group data than pandas groupby,我设法将它降低到4秒钟。但是,我正在寻找更快的选择。我对Python和Stack Overflow还是很陌生,所以我真的希望有人能帮助我!

有按需量和容量预测的数据,以及从每个仓库运送每个客户的成本。 df_demand的片段如下所示,但实际尺寸较大(索引仅为0,1,2,...):

date         customer    shift           orders        deliveries       slot        
2020-10-21          A        1              108                 9     Evening
2020-10-21          A        2               97                 8     Evening
2020-10-21          A        1               55                 5     Morning
2020-10-21          B        1              110                 8     Evening
2020-10-21          B        2               92                 7     Evening 
2020-10-21          B        1               54                 4     Morning
...
...
...
2020-10-22          A        1               58                 5     Evening             
2020-10-22          A        2              118                 8     Evening 
2020-10-22          A        1               66                 5     Morning
2020-10-22          B        1              106                 8     Evening 
2020-10-22          B        2              108                 8     Evening
2020-10-22          B        1              135                10     Morning

和df_capacity的代码段看起来像

date             warehouse          orders          slot
2020-10-21             WH1            2970       Evening
2020-10-21             WH1             669       Morning
2020-10-21             WH2            3112       Evening
2020-10-21             WH2             909       Morning
2020-10-21             WH3            3257       Evening
2020-10-21             WH3             773       Morning
...
...
...
2020-10-22             WH1            3170       Evening
2020-10-22             WH1             794       Morning
2020-10-22             WH2            4436       Evening
2020-10-22             WH2             788       Morning
2020-10-22             WH3            4307       Evening
2020-10-22             WH3             617       Morning

和df_costs的摘要是(其中df_costs的索引是客户A,B,C等):

index   WH1     WH2     WH3    WH4
A       30.2    54.3   76.3   30.9
B       96.2    34.2   87.7   102.4
C       57.0    99.5   76.4   34.5
...

现在,我的目标是计算总受限需求(对于每天和每个仓库,这等于其最小容量和分配给它的订单),总运输成本(对于每个客户-仓库组合的数量交付数量除以20是所需的卡车驱动器数量,然后乘以每个卡车驱动器的成本:df_costs,然后乘以每个仓库的最大利用率和最小利用率(每个仓库的利用率等于分配给仓库的总需求仓库除以其总容量)。接下来,evaluate应该返回适​​应度值。我已经完成了以下工作,但是效果还不够快。我希望问题在于evaluate中的运算速度,但我也会与其他人分享上下文。

def evaluate(individual,df_demand,df_capacity,df_costs):
    df_demand["warehouse"] = pd.Series(individual).values

    truck_drives_per_cust_wh = np.ceil(
        df_demand.pivot_table(index=["customer","warehouse"],columns=["date","slot"],values="deliveries",aggfunc="sum",fill_value=0).div(20))
    transportation_cost = truck_drives_per_cust_wh.mul(
        df_costs.stack(),axis="rows").sum().sum()
    
    orders_per_warehouse = df_demand.pivot_table(
        index=["warehouse",columns=["date"],values="orders",fill_value=0)
    constrained_demand = np.fmin(
        orders_per_warehouse,df_capacity.pivot_table(index=["warehouse",fill_value=0)).sum().sum()

    utilization_per_warehouse = df_demand.pivot_table(
        index="warehouse",fill_value=0).div(df_capacity.pivot_table(index="warehouse",fill_value=0),axis="rows")
    
    fitness = max(utilization_per_warehouse.loc[:,"orders"]) * (constrained_demand - transportation_cost)
    
    return fitness

def set_fitness(population,df_costs):
    fitnesses = [(individual,tbx.evaluate(individual,df_costs)) for individual in population]
    for individual,fitness in fitnesses:
        individual.fitness.values = fitness



population = tbx.population(n=100)
set_fitness(population,df_costs)
   
    

这里,个人是与df_demand长度完全相同的列表,由所有仓库的随机组合组成:individual = ['WH1','WH1','WH3','WH4','WH2',...],人口是100个不同个体的组合。

我的问题是:实现上述操作最快/最好的方法是什么?特别是evaluate中的操作? 到现在为止,我还没有使它比现在更快地工作,所以任何帮助将不胜感激!如果不清楚或您有其他意见,请告诉我!

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)