0
votes

Méthode FIFO utilisant numpy

Je voudrais implémenter la méthode FIFO en utilisant numpy. Plus précisément, j'ai un tableau numpy STOCK qui ressemble à ceci

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

, où chaque ligne représente une catégorie de produits différente et chaque colonne le nombre d'articles achetés à un endroit spécifique date.

Maintenant, j'ai un deuxième tableau SOLD qui ressemble à ceci

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

où chaque nombre représente le nombre de produits vendu par catégorie.

Je souhaite maintenant mettre à jour le tableau STOCK en utilisant le Méthode FIFO . Cela signifie que je souhaite réserver les n premiers éléments cumulés par catégorie de produit. Dans le cas ci-dessus, la sortie devrait être quelque chose comme

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]])

Pourtant, je ne sais pas comment résoudre ce problème. Des idées?


0 commentaires

3 Réponses :


0
votes

J'espère que cela vous convient.

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


2 commentaires

Bien, ça devrait marcher! Mais pensez-vous que nous pouvons vectoriser ce problème? Je pense que cela pourrait être un peu lent ... surtout si nous augmentons le nombre de pas de temps de 10 à, disons, 1000.


En fait, il ne sera pas influencé par le nombre de colonne de STOCK puisque l'algorithme s'arrête lorsque SOLD est nul.



0
votes

Une manière plus condensée, en utilisant 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()))))

Essentiellement, vous faites une somme cumulative sur le tableau, retirez le out , coupez à 0 et additionnez-le. Cela reproduira un processus de type FIFO. Cela fonctionne vectorisé.


0 commentaires

0
votes

Mise à jour: j'ai trouvé une solution assez rapide (similaire à celle de Mstaino)

%timeit book_out(STOCK.copy(), SOLD.copy())
> 1.13 ms ± 5.79 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
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


0 commentaires