繁体   English   中英

为什么我的 Python 代码运行这么慢? 我怎样才能加快速度?

[英]Why is my Python code running so slow? How can I speed it up?

我正在编写与库存管理相关的代码。 我写了一个关于最新日期的代码,为即将缺货的产品提供新产品。

这是我目前的数据。

df = pd.DataFrame({
    'SKU' : ["20651","27394","28443","27766","23767","24704","27824","19612","27339","27851"],
    'DailyMean': [6,9,6,7,9,3,4,8,7,1],
    'Stock': [8,15,9,5,4,11,19,16,28,29],
    'LeadTime': [5,6,6,8,3,7,4,1,8,1],
    'alert': [False,False,False,False,False,False,True,True,False,True],
    'LeadDate': ["2021-05-11","2021-05-11","2021-05-11","2021-05-11","2021-05-11","2021-05-11","2021-05-11","2021-05-11","2021-05-11","2021-05-11",]                    
})

    SKU   DailyMean  Stock  LeadTime    alert   LeadDate
0   20651      6       8       5        False   2021-05-11
1   27394      9      15       6        False   2021-05-11
2   28443      6       9       6        False   2021-05-11
3   27766      7       5       8        False   2021-05-11
4   23767      9       4       3        False   2021-05-11
5   24704      3      11       7        False   2021-05-11
6   27824      4      19       4        True    2021-05-11
7   19612      8      16       1        True    2021-05-11
8   27339      7      28       8        False   2021-05-11
9   27851      1      29       1        True    2021-05-11

这是我写的代码。

for i in range(len(df)):
    new_stock = df.Stock[i]
    x = 0
    
    while((new_stock - (df.LeadTime[i] * df.DailyMean[i])) > 0):
        new_stock = new_stock - (df.LeadTime[i] * df.DailyOrder[i])
        if new_stock >= 0:
            x = x + 1

    df.LeadDate[i] = df.LeadDate[i] + datetime.timedelta(days=x)

这是我所期望的。

    SKU   DailyMean  Stock  LeadTime    alert   LeadDate
0   20651      6       8       5        False   2021-05-11
1   27394      9      15       6        False   2021-05-11
2   28443      6       9       6        False   2021-05-11
3   27766      7       5       8        False   2021-05-11
4   23767      9       4       3        False   2021-05-11
5   24704      3      11       7        False   2021-05-11
6   27824      4      19       4        True    2021-05-12
7   19612      8      16       1        True    2021-05-12
8   27339      7      28       8        False   2021-05-11
9   27851      1      29       1        True    2021-06-08

这段代码也在大数据上运行了很长时间。 如何优化此代码以更快地运行。

我认为你的问题是糟糕的算法复杂性:循环中的代码在你想要 O(1) 的地方具有 O(n) 复杂性。

我不太了解您的代码的语义,所以我猜您想要实现以下目标:

  • 您有一定数量的资源(称为stock
  • 该资源将定期减少(您通过减去leadTime * dailyMean表示)
  • 您想知道:在多少时间段内,我仍有可用资源——或者,换一种说法:我什么时候会用完这些资源?

因此,您的代码要回答的问题是:如果我有 500 件库存,并且我定期卖出 10 件,我会在多少个时期内缺货?

您使用循环实现了这一点:

stock = 500
daily_reduction = 10
days = 0
while (stock - daily_reduction) >= 0:
    days += 1
    stock -= daily_reduction

这里的重要方面如下:对于这个计算,循环必须运行days ,所以我们有 O(n) 复杂度。 很容易看出我们如何可以更快地计算:

stock = 500
daily_reduction = 10
days = stock // daily_reduction  # // is integer divion, which we want here.

此代码只需进行一次除法即可获得结果,因此它以 O(1) 复杂度运行。

此外,您有一个pandas.DataFrame ,但您正在 python 中手动进行计算。 您可能想要执行以下操作:

# element-wise division of the elements: How often can we subtract until we hit 0?
subtract_counts = df.Stock // (df.LeadTime * df.DailyMean)

# transform numbers to datetimes
days_to_add = subtract_counts.apply(lambda x: datetime.timedelta(days=x))

# element-wise add
df.LeadDate += days_to_add

注意:这个计算有点不同:你的 while 循环有条件> 0 ,但在这里我们在语义上使用>= 0 ,但我认为你还是想这样做? 如果我误解了,请纠正我。

这种方法应该运行得相当快,也适用于大量数据。 您提供的(非常小的)样本数据的基准表明速度提高了 4 倍,即使大多数列的内部 while 循环都没有执行一次。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM