我想使用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
但是,我不确定如何解决此问题。有什么想法吗?
答案 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)