使用numpy的FIFO方法

2024-05-08 12:12:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我想用numpy实现FIFO方法。具体来说,我有一个numpy数组STOCK,如下所示

import numpy

numpy.random.seed(1)
STOCK = numpy.random.randint(1, 9, size=(10_000, 10)) 

STOCK = array([
       [6, 4, 5, ..., 6, 8, 1],
       [1, 2, 5, ..., 2, 3, 5],
       [7, 6, 3, ..., 5, 6, 7],
       ...,
       [2, 5, 8, ..., 7, 6, 1],
       [2, 8, 7, ..., 2, 8, 4],
       [1, 2, 6, ..., 1, 1, 3]])

,其中每行表示不同的产品类别,每列表示在特定日期购买的商品数量。你知道吗

现在,我有第二个数组SOLD,看起来像这样

SOLD = numpy.random.randint(1, 9, size=10_000)
SOLD = array([1, 7, 3, ..., 6, 8, 5])

其中每个数字代表每个类别销售的产品数量。你知道吗

现在我想用FIFO方法更新STOCK数组。意思是,我想预订每个产品类别的前n个累计元素。在上面的例子中,输出应该是

UPDATED_STOCK= array([
       [5, 4, 5, ..., 6, 8, 1],  # 6-1, 4, 5,     ... BOOKED OUT=1
       [0, 0, 1, ..., 2, 3, 5],  # 1-1, 2-2, 5-4, ... BOOKED OUT=7
       [4, 6, 3, ..., 5, 6, 7],  # 7-3, 6, 3,     ... BOOKED OUT=3
       ...,
       [0, 1, 8, ..., 7, 6, 1],  # 2-2, 5-4, 8,   ... BOOKED OUT=6
       [0, 2, 7, ..., 2, 8, 4],  # 2-2, 8-6, 7,   ... BOOKED OUT=8
       [0, 0, 4, ..., 1, 1, 3]]) # 1-1, 2-2, 6-2, ... BOOKED OUT=5

然而,我不确定如何解决这个问题。有什么想法吗?你知道吗


Tags: 方法importnumpysizestockrandom数组out
3条回答

我希望这是合适的。你知道吗

import numpy as np
np.random.seed(1)

STOCK = np.random.randint(1, 9, size=(10000, 10))
SOLD = np.random.randint(1, 9, size=10000)

i = 0

while SOLD.sum() > 0:
    # The minimum between the ith column of STOCK and SOLD
    MIN = np.minimum(SOLD, STOCK[:, i])

    STOCK[:, i] -= MIN
    SOLD -= MIN

    i += 1

更新:我找到了一个非常快速的解决方案(类似于Mstaino的解决方案)

numpy.random.seed(1) 
STOCK = numpy.random.randint(1, 9, size=(10_000, 10))  
SOLD = numpy.random.randint(1, 9, size=10_000) 

def book_out(stock, sold):
    booking_out = numpy.minimum(stock.cumsum(axis=1), sold[:,None])
    booking_out[:,1:] -= booking_out[:,:-1] 
    stock -= booking_out
%timeit book_out(STOCK.copy(), SOLD.copy())
> 1.13 ms ± 5.79 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

更简洁的方式,使用cumsum

import numpy as np
x = np.random.randint(1,10, size=(7, 5))
out = np.random.randint(1,10, size=(7, 1))
print(x, out)

cum = x.cumsum(1)
np.diff(np.hstack((np.zeros(x.shape[0])[:,None], np.clip(cum - out, 0, cum.max()))))

基本上,对数组进行累加求和,取出out,在0处剪裁并求和。这将重现类似FIFO的过程。它是矢量化的。你知道吗

相关问题 更多 >