比pandas groupby更快的数据分组方式

问题描述

我正在实施遗传算法。对于此算法,必须进行多次迭代(介于100到500之间),其中在每次迭代中都要评估所有100个个体的“适应性”。在此程度上,我已经编写了一个评估函数。但是,即使是一次迭代,评估100个人的适应度也已经花费了13秒。为了实现高效的算法,我必须大幅度加快速度。

valuate函数接受两个参数,然后执行一些计算。我将共享部分函数,​​因为此后将重复类似的计算形式。具体来说,我现在对名为df_demand的数据帧执行分组,然后取列表理解的总和,该列表推导使用来自groupby函数的结果数据帧和另一个名为df_distance的数据帧。 df_demand的片段如下所示,但实际尺寸较大(索引仅为0,1,2,...):

date         customer    deliveries   warehouse   
2020-10-21          A            30           1
2020-10-21          A            47           1
2020-10-21          A            59           2
2020-10-21          B           130           3
2020-10-21          B           102           3 
2020-10-21          B            95           2
2020-10-22          A            55           1             
2020-10-22          A            46           4 
2020-10-22          A            57           4
2020-10-22          B            89           3 
2020-10-22          B           104           3
2020-10-22          B           106           4

和df_distance的摘要是(其中的列是仓库):

index   1     2      3       4
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

接下来,我要对df_demand进行分组,以使(日期,客户,仓库)的每个组合出现一次,并汇总该组合的所有交货。最后,我要计算总成本。目前,我已经完成了以下操作,但这太慢了:

def evaluate(df_demand,df_distance):
    costs = df_demand.groupby(["date","customer","warehouse"]).sum().reset_index()
    cost = sum([math.ceil(costs.iat[i,3] / 20) * df_distance.loc[costs.iat[i,1],costs.iat[i,2]] for i in range(len(costs))])

    etc... 
    return cost

由于我必须进行多次迭代,并且考虑到数据的维数要大得多这一事实,所以我的问题是:执行此操作的最快方法是什么?

解决方法

尝试:

def get_cost(df,df2):
    '''
    df: deliveries data
    df2: distance data
    '''
    pivot = np.ceil(df.pivot_table(index=['customer','warehouse'],columns=['date'],values='deliveries',aggfunc='sum',fill_value=0)
                      .div(20)
                   )
    
    return pivot.mul(df2.rename_axis(index='customer',columns='warehouse').stack(),axis='rows').sum().sum()