Python 创建库存历史记录的最有效方法是什么

Python 创建库存历史记录的最有效方法是什么,python,pandas,pandas-groupby,Python,Pandas,Pandas Groupby,我想知道,一年中的每一天,我有多少辆车在库存,每辆车在那一天有多少天在库存 我有移动的完整历史记录(每辆车进出库存的时间戳-出租、出售、维修等)。像这样: car in out status_id operation PZR4010 08/02/2018 08:55 08/02/2018 16:29 12 out_stock QRX0502 07/02/2018 09:00 07/02/2018 10:28

我想知道,一年中的每一天,我有多少辆车在库存,每辆车在那一天有多少天在库存

我有移动的完整历史记录(每辆车进出库存的时间戳-出租、出售、维修等)。像这样:

car             in          out        status_id    operation
PZR4010 08/02/2018 08:55    08/02/2018 16:29    12  out_stock
QRX0502 07/02/2018 09:00    07/02/2018 10:28    7   in_stock
PYR8269 06/02/2018 17:10    09/02/2018 21:22    12  in_stock
QRG6455 06/02/2018 12:39                        8   sold
QRU1867 08/02/2018 08:00    09/02/2018 11:07    12  in_stock
PZR8528 06/02/2018 17:51    07/02/2018 07:46    10  out_stock
PZR7184 06/02/2018 16:00    08/02/2018 12:10    7   in_stock
PZR0386 08/02/2018 09:02    14/02/2018 14:53    10  out_stock
PZR8600 06/02/2018 16:00    07/02/2018 07:34    7   in_stock
PZR1787 06/02/2018 17:02    20/02/2018 17:33    12  in_stock
所以,对于每一辆车,我必须加入到它的库存中,知道它在那种状态下有多长时间

例如:

car     in                 out          status_id   operation
QRX0502 08/02/2018 08:55    09/02/2018 16:29    7   in_stock
QRX0502 07/02/2018 09:00    08/02/2018 08:55    7   in_stock
QRX0502 06/02/2018 17:10    07/02/2018 09:00    7   in_stock
将变得简单:

car          in                 out            status_id    operation
QRX0502 06/02/2018 17:10    09/02/2018 16:29    7   in_stock
在“输入”列中捕获最小时间戳,在“输出”列中捕获最大时间戳

我已尝试使用groupby+shift:

#'mov'是包含所有股票运动的数据帧
#我创建了一个列以更好地过滤groupby
mov['aux']=mov['car']+“-”+mov['operation']
#创建要作为输出的基本数据帧
hist_mov=pd.DataFrame(columns=list(mov.columns))
对于行,在mov.groupby(mov['aux'].ne(mov['aux'].shift()).cumsum()中操作:
g_temp=操作。分组方式(['car','operation',],
.agg({'in':'min','out':'max'}).reset_index()
历史移动=历史移动附加(g\u temp,sort=True)
问题是整个数据库运行大约需要16个小时,我必须每天运行它,以更新库存状态

我想建立一些类似于:

添加到历史记录中的每一新行都将检查它是否与我的新基(hist_mov)中的任何一行连续。如果是,请更新该行。如果不是,则添加为新行


有什么想法吗?谢谢

我想这可能就是你想要的:

cols = ["car", "operation"]
pd.merge(df.groupby(cols)["in"].min().reset_index(), 
         df.groupby(cols)["out"].max().reset_index(), on=cols, how="outer")
编辑:

希望通过使用
trans_id
列来识别车辆进出的不同实例,这可以缓解评论中概述的问题:

df['trans_id'] = df['operation'].ne(df['operation'].shift()).astype(int) + df.index
cols = ["car", "trans_id", "operation"]
df_grouped = pd.merge(df.groupby(cols)["in"].min().reset_index(), 
         df.groupby(cols)["out"].max().reset_index(), on=cols, how="outer")
df_grouped.drop('trans_id', axis=1, inplace=True)
df_grouped

我想这可能就是你想要的:

cols = ["car", "operation"]
pd.merge(df.groupby(cols)["in"].min().reset_index(), 
         df.groupby(cols)["out"].max().reset_index(), on=cols, how="outer")
编辑:

希望通过使用
trans_id
列来识别车辆进出的不同实例,这可以缓解评论中概述的问题:

df['trans_id'] = df['operation'].ne(df['operation'].shift()).astype(int) + df.index
cols = ["car", "trans_id", "operation"]
df_grouped = pd.merge(df.groupby(cols)["in"].min().reset_index(), 
         df.groupby(cols)["out"].max().reset_index(), on=cols, how="outer")
df_grouped.drop('trans_id', axis=1, inplace=True)
df_grouped

我找到了答案

我第一次发布的代码几乎正确,但它有一个不必要的循环

1-首先,我按车辆和状态变化数据对项目进行排序:

mov=mov.sort_值(['car','in',升序=False)
2-然后我开车去集束,并进行操作:

mov['aux']=mov['car']+“-”+mov['operation']
mov['cluster']=(mov.aux!=mov.aux.shift()).cumsum()
3-最后,我可以根据此群集Id进行分组,并获得最小“输入”值和最大“输出”值:

hist_mov=mov.groupby(['cluster','car','operation']).agg({'in':'min',
'out':'max'}).reset_index().copy()

我找到了答案

我第一次发布的代码几乎正确,但它有一个不必要的循环

1-首先,我按车辆和状态变化数据对项目进行排序:

mov=mov.sort_值(['car','in',升序=False)
2-然后我开车去集束,并进行操作:

mov['aux']=mov['car']+“-”+mov['operation']
mov['cluster']=(mov.aux!=mov.aux.shift()).cumsum()
3-最后,我可以根据此群集Id进行分组,并获得最小“输入”值和最大“输出”值:

hist_mov=mov.groupby(['cluster','car','operation']).agg({'in':'min',
'out':'max'}).reset_index().copy()

此时,中的状态id并不重要。Is仅用于确定操作。合并解决方案不起作用,因为汽车可能有很长时间的库存,然后缺货,然后又有库存,等等。我想捕捉整个运动。使用此解决方案,每辆车只有一行“库存”和一行“缺货”。谢谢你的帮助!不幸的是没有。我认为它仍然需要循环,因为一个库存可以链接到另一个库存,然后依次类推,直到我找到每辆车在每个状态下的最大连续间隔@你如何知道一辆库存是否与另一辆库存相关联?如果时间戳out等于ohter行的时间戳in:so here:car in out status\u id operation QRX0502 08/02/2018 08:55 09/02/2018 16:29 7库存QRX0502 07/02/2018 09:00 08/02/2018 08:55 7库存QRX0502 06/02/2018 17:10 07/02/2018 09:00 7库存我知道这款on从06/02到09/02都在库存中,因为时间戳正在形成一个序列:“out”与以下“in”相同(并且仍然具有库存状态)。如果是一个缺货的中间环节,它应该会中断链接,我无法在这里粘贴为表,但我使用了相同的问题示例“因此,例如:…”直到“将变得简单”状态id在这一点上并不重要。Is仅用于确定操作。合并解决方案不起作用,因为汽车可能有很长时间的库存,然后缺货,然后又有库存,等等。我想捕捉整个运动。使用此解决方案,每辆车只有一行“库存”和一行“缺货”。谢谢你的帮助!不幸的是没有。我认为它仍然需要循环,因为一个库存可以链接到另一个库存,然后依次类推,直到我找到每辆车在每个状态下的最大连续间隔@你如何知道一辆库存是否与另一辆库存相关联?如果时间戳out等于ohter行的时间戳in:so here:car in out status\u id operation QRX0502 08/02/2018 08:55 09/02/2018 16:29 7库存QRX0502 07/02/2018 09:00 08/02/2018 08:55 7库存QRX0502 06/02/2018 17:10 07/02/2018 09:00 7库存我知道这款on从06/02到09/02都在库存中,因为时间戳正在形成一个序列:“out”与以下“in”相同(并且仍然具有库存状态)。如果是介于两者之间的缺货,它应该会断开我无法粘贴为表的链接,但我使用了相同的示例