为什么 Pandas 不在这里同时添加两列?
Why is Pandas not adding two columns at the same time here?
我目前正在开发一个 "restocker" 模拟器,它从与实际不同的库存位置开始,每天接收实际销售的输入,并且必须完成 3 个任务:
- 今天销售后更新所有商店所有商品的库存情况
- 验证当前库存头寸是否达到"re-stock point"(全部库存头寸的85%)
- 计算
LEAD_TIME
后所有商店所有商品的重新库存(每个商店有不同的 LEAD_TIME
)
首先我要列出你们需要知道的所有概念:
GRID
- 可以描述为 "stock target" 最大股票头寸。
在第一天的操作中,股票头寸等于 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)保存在字典中。
- 更新当天销售额后的所有值
- 重新计算所有字典值
由于代码繁杂,我把整个notebook都公开了where(里面有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 是减法而不是加法?
我不确定为什么您的代码不起作用,但是有一种更好的矢量化方法来执行您希望执行的计算。此方法也可以解决您的问题。
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)
我目前正在开发一个 "restocker" 模拟器,它从与实际不同的库存位置开始,每天接收实际销售的输入,并且必须完成 3 个任务:
- 今天销售后更新所有商店所有商品的库存情况
- 验证当前库存头寸是否达到"re-stock point"(全部库存头寸的85%)
- 计算
LEAD_TIME
后所有商店所有商品的重新库存(每个商店有不同的LEAD_TIME
)
首先我要列出你们需要知道的所有概念:
GRID
- 可以描述为 "stock target" 最大股票头寸。 在第一天的操作中,股票头寸等于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)保存在字典中。
- 更新当天销售额后的所有值
- 重新计算所有字典值
由于代码繁杂,我把整个notebook都公开了where(里面有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 是减法而不是加法?
我不确定为什么您的代码不起作用,但是有一种更好的矢量化方法来执行您希望执行的计算。此方法也可以解决您的问题。
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)