Почему Панды не добавляют здесь два столбца одновременно?

В настоящее время я работаю над симулятором "пополнения запасов", который начинается с позиции на складе, отличной от фактической, получает ежедневные данные о фактических продажах и выполняет 3 задачи:

  • обновить позиции на складе для всех магазинов во всех магазинах после сегодняшних продаж
  • проверить, достигла ли текущая позиция на складе "точки пополнения" (85% от полной позиции на складе)
  • рассчитать запас для всех магазинов во всех магазинах после LEAD_TIME (у каждого магазина свой LEAD_TIME)

Сначала я изложу все концепции, которые вы, ребята, должны знать:

  • GRID - Можно описать как "цель акций" максимальную позицию по акциям. В первый день работы складская позиция равна GRID и пополнение запасов всегда будет пытаться вернуть позицию на складе GRID

  • В целях упрощения мы будем использовать фиксированную GRID, но в действительности эта GRID должна быть динамичной и пересчитываться после каждого пополнения запаса.

  • SIM_SALES = SALES

  • SIM_STOCK(day n) = SIM_STOCK(day n-1) - SALES(day n) + RESTOCK(day n)

  • Если SIM_STOCK - SALES <= 0, SALES дня также будет приниматься равным нулю.

Структура DataFrame идет примерно так (пример с ОДИН ITEM - ОДИН STORE) и содержит фактические значения:

INDEX      ITEM     STORE   STOCK(UN)   SALES(UN)   DAY     LEAD_TIME    GRID   
0          4058855  1000    173         0           1       5            55
1          4058855  1000    172         1           2       5            55
2          4058855  1000    163         9           3       5            55
3          4058855  1000    149         14          4       5            55

Аналогично, наша имитированная сетка будет выглядеть так:

INDEX      ITEM     STORE   STOCK(UN)   SALES(UN)   DAY     LEAD_TIME    GRID      KEY      RESTOCK      COUNTER    
 0         4058855  1000    55          0           1       5            55        False    0            0
 1         4058855  1000    0           0           2       5            55        False    0            0
 2         4058855  1000    0           0           3       5            55        False    0            0
 3         4058855  1000    0           0           4       5            55        False    0            0

Я ищу вот что:

INDEX      ITEM     STORE   SIM_STOCK(UN)   SIM_SALES(UN)   DAY     LEAD_TIME    GRID      KEY      RESTOCK      COUNTER    
0          4058855  1000    55              0               1       5            55        False    0            0
1          4058855  1000    54              1               2       5            55        False    0            0
2          4058855  1000    45              9               3       5            55        True     0            5
3          4058855  1000    31              14              4       5            55        True     0            4
4          4058855  1000    24              7               5       5            55        True     0            3
5          4058855  1000    15              9               6       5            55        True     0            2
6          4058855  1000    19              6               7       5            55        True     10           1
7          4058855  1000    11              8               8       5            55        True     0            5
8          4058855  1000    3               8               9       5            55        True     0            4

Я пришел к решению в 3 этапа:

  • Сохраняйте все значения (Stock, Sales, Key и Counter) в словарях.
  • Обновить все значения после текущих продаж
  • Пересчитать все значения словарей

Так как код очень обширный и сложный, я опубликовал всю записную книжку, где (там есть CSV-файл)

Но важной частью является то, что это фактическое DataFrame что я получаю:

INDEX      ITEM     STORE   SIM_STOCK(UN)   SIM_SALES(UN)   DAY     LEAD_TIME    GRID      KEY      RESTOCK      COUNTER    
0          4058855  1000    55              0               1       5            55        False    0            0
1          4058855  1000    54              1               2       5            55        False    0            0
2          4058855  1000    45              9               3       5            55        True     0            5
3          4058855  1000    31              14              4       5            55        True     0            4
4          4058855  1000    24              7               5       5            55        True     0            3
5          4058855  1000    15              9               6       5            55        True     0            2
6          4058855  1000    9               6               7       5            55        True     10           1
7          4058855  1000    1               8               8       5            55        True     0            5
8          4058855  1000    1               0               9       5            55        True     0            4

Код делает все, кроме как, чтобы добавить RESTOCK, Вот часть кода, где я добавляю RESTOCK и вычесть SALES:

DF['SIM_STOCK'] = DF.apply(lambda row:(dict_est[(row['ITEM'],row['STORE'],row['DAY']-1)]
                                          -row['SIM_SALES']
                                          +row['RESTOCK']) 
                              if row['DAY'] == CURRENT_DAY 
                              else row['SIM_STOCK'], 
                              axis=1)

Почему Pandas вычитает, но не добавляет, если обе операции происходят в одной строке кода?

2 ответа

Решение

Я не уверен, почему ваш код не работает, но есть гораздо лучший, векторизованный способ выполнения вычислений, которые вы хотите выполнить. Этот метод также может решить вашу проблему.

DF['DICT_KEY'] = list(zip(DF['ITEM'], DF['STORE'], DF['DAY']-1))

DF['SIM_STOCK'] = np.where(DF['DAY'] == CURRENT_DAY,
                           DF['DICT_KEY'].map(dict_est) - DF['SIM_SALES'] + DF['RESTOCK'],
                           DF['SIM_STOCK'])

объяснение

  • Создать pd.Series кортежей, которые затем подают в качестве ключей кdict_est,
  • использование np.where указать свой if / else условия.

Проблема была на самом деле довольно простой...

Я пытался получить значение из столбца DF['RESTOCK], следующее:

DF['RESTOCK'] = np.where(DF['COUNTER'] == 1, 
                       DF['DICT_RESTOCK'].map(dict_RST), 
                       0)

Но DF['COUNTER'] столбец обновляется после обоих RESTOCK а также STOCK,

Это правильный способ получить значение:

DF['ABAST'] = np.where(((DF['DICT_KEY'].map(dc) == 1)&(DF['DAY'] == DIA_ATUAL))
                       |(DF['COUNTER'] == 1), 
                      DF['DICT_ABAST'].map(dict_abs), 
                      0)
Другие вопросы по тегам