我试图从Pandas复制以下逻辑,但是使用Numpy向量化。
此外,我觉得可能有一种更Python化的方式来添加Actual Available
列,而无需先创建两个单独的变量series_1
和series_2
,而且这也不冗长。>
[Actual Available]
背后的逻辑是,
[Actual Available] = [Stock] + [Requirements] + [Receipts]
,[Actual Available] = [Prev row of Actual Available] + [Requirements] + [Receipts]
有什么想法吗?
import pandas as pd
import numpy as np
df = pd.DataFrame({
"Material": ["ABC", "ABC", "ABC", "ABC", "XYZ", "XYZ", "XYZ"],
"Plant": [2685, 2685, 2685, 2685, 2685, 2685, 2685],
"Year": ["2020", "2020", "2020", "2020", "2020", "2020", "2020"],
"Week": [1, 2, 3, 4, 1, 2, 3],
"Stock": [30, 30, 30, 30, 70, 70, 70],
"Requirements": [10, 15, 20, 25, 20, 30, 40],
"Receipts": [1, 2, 3, 4, 11, 12, 13]
})
print(df)
# Add [Is First?] column
df["Is First?"] = np.where(
(df["Material"] == df["Material"].shift(1)) &
(df["Plant"] == df["Plant"].shift(1)),
False,
True,
)
# Add [Actual Available] column
df["Actual Available"] = (df["Stock"] + df["Requirements"] +
df["Receipts"]).where(df["Is First?"].eq(True))
series_1 = df["Is First?"].eq(True).cumsum()
series_2 = (df["Actual Available"].ffill() +
(df["Receipts"] +
df["Requirements"]).shift(-1).groupby(series_1).cumsum().shift())
df["Actual Available"] = df["Actual Available"].fillna(series_2)
print(df)
答案 0 :(得分:1)
从您的初始DataFrame开始,所有这些逻辑似乎是添加到“库存”栏中的“ {Requires”(需求)+“ Receipts”(收据)的groupby
+ cumsum
,因为“ Stock”已经在整个过程中重复了小组。
df["Actual Available"] = df['Stock'] + df.groupby(['Material', 'Plant'])[['Requirements', 'Receipts']].cumsum().sum(1)
Material Plant Year Week Stock Requirements Receipts Actual Available
0 ABC 2685 2020 1 30 10 1 41
1 ABC 2685 2020 2 30 15 2 58
2 ABC 2685 2020 3 30 20 3 81
3 ABC 2685 2020 4 30 25 4 110
4 XYZ 2685 2020 1 70 20 11 101
5 XYZ 2685 2020 2 70 30 12 143
6 XYZ 2685 2020 3 70 40 13 196
在“向量化”方面,pandas
建立在numpy
上,因此性能就在那里。此外,pandas
在许多操作上都付出了额外的努力。 DataFrame.GroupBy.cumsum()
在cython
中实现了快速通道,因此已经进行了很多优化。