使用numpy的FIFO方法

时间:2019-11-11 14:23:59

标签: python arrays numpy fifo

我想使用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

但是,我不确定如何解决此问题。有什么想法吗?

3 个答案:

答案 0 :(得分:0)

我希望这是合适的。

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

答案 1 :(得分:0)

一种更简洁的方式,使用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的过程。它可以向量化。

答案 2 :(得分:0)

更新:我找到了一种非常快速的解决方案(类似于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)