我有一个Pandas数据框(以说明预期的行为),如下所示:
yyyy-MM-dd'T'hh:mm:ss.SSSXXX
df = pd.DataFrame({
'Id': ['001', '001', '002', '002'],
'Date': ['2013-01-07', '2013-01-14', '2013-01-07', '2013-01-14'],
'Purchase_Quantity': [12, 13, 10, 6],
'lead_time': [4, 2, 6, 4],
'Order_Quantity': [21, 34, 21, 13]
})
df['Date'] = pd.to_datetime(df['Date'])
df = df.groupby(['Id', 'Date']).agg({
'Purchase_Quantity': sum,
'lead_time': sum,
'Order_Quantity': sum})
Purchase_Quantity lead_time Order_Quantity
Id Date
001 2013-01-07 12 4 21
2013-01-14 13 2 34
002 2013-01-07 10 6 21
2013-01-14 6 4 13
是以天为单位的持续时间。
我想添加一列来跟踪“现有数量”:
预期结果应为:
lead_time
答案 0 :(得分:0)
我认为您应该照顾itertools.accumulate
来构建新行(而不是迭代数据框行)。
这是第一次尝试。我将对其进行更新,以更好地匹配您在编辑中尝试实现的目标。
diff = df['Order_Quantity'] - df['Purchase_Quantity']
acc = list(itertools.accumulate(diff))
df['on_hand'] = acc
print(df)
我想我误解了您试图实现的目标。
这是您的基本数据框:
Purchase_Quantity lead_time Order_Quantity
Id Date
001 2013-01-07 12 4 21
2013-01-14 13 2 34
002 2013-01-07 10 6 21
2013-01-14 6 4 13
根据我的理解,On Hand
列必须报告尚未到达的“已购买”物品的数量。看起来像这样:
Purchase_Quantity lead_time On_Hand
Id Date
001 2013-01-07 12 4 12
2013-01-14 13 2 25 # (12 + 13)
002 2013-01-07 10 6 10
2013-01-14 6 4 16 # (10 + 6)
我了解得很好吗?如果是这样,Order_Quantity
的作用是什么?
这是一个受this post启发的新示例,它似乎与您的用例匹配。
我更改了列名以避免混淆(“ Order”和“ Purchase”之间的区别是用我的语言翻译成相同的单词...)。
您还应该将提前期转换为datetime.timedelta
对象,使单位和计算更加清晰。
import pandas as pd
def main():
df = pd.DataFrame({
'Id': ['001', '001', '002', '002'],
'Date': ['2013-01-07', '2013-01-14', '2013-01-07', '2013-01-14'],
'Ordered': [21, 34, 21, 13],
'LeadTime': [4, 2, 6, 4],
'Sold': [12, 13, 10, 6],
})
df['Date'] = pd.to_datetime(df['Date'])
df['LeadTime'] = pd.to_timedelta(df['LeadTime'], unit="days")
print(df)
df['Received'] = df.apply(lambda x: df.loc[(df['Date']+df['LeadTime'] <= x['Date']) & (df['Id'] == x['Id']), "Ordered"].sum(), axis=1)
df['Diff'] = df['Received'] - df['Sold']
print(df)
if __name__ == '__main__':
main()
如此处所示,您可能必须分两步进行。首先建立一个新列,其值取决于行的当前值(请参阅链接的文章)。然后进行其他可以向量化的计算。
这仍然不能提供预期的输出,但是我提供了一个很好的起点。