我试图获取一年中的每一天的库存量以及该日期每辆车的库存天数。
我有完整的行驶历史(每辆车进出和移出的时间戳-出租,出售,维修等)。像这样:
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' is the dataframe with all the stock movements
# I create a columns to better filter on the groupby
mov['aux']=mov['car']+" - "+mov['operation']
#creating the base dataframe to be the output
hist_mov=pd.DataFrame(columns=list(mov.columns))
for line, operation in mov.groupby(mov['aux'].ne(mov['aux'].shift()).cumsum()):
g_temp=operation.groupby(['car','operation',
'aux']).agg({'in':'min','out':'max'}).reset_index()
hist_mov=hist_mov.append(g_temp,sort=True)
问题在于整个数据库需要大约16个小时来运行,而我每天都必须运行它以更新库存状态。
我想构建类似的东西
添加到历史记录的每个新行都将检查它是否与我的新库(hist_mov)中的任何一个连续。如果是这样,请更新该行。如果没有,请添加为新行。
有什么想法吗?谢谢!
答案 0 :(得分:0)
我认为您可能追求的是这样的事情
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 :(得分:0)
我找到了答案!
我最初发布的代码几乎是正确的,但是有一个不必要的循环。
1-首先,我按汽车和状态变化数据对项目进行排序:
mov=mov.sort_values(['car','in'],ascending=False)
2-然后我乘汽车和汽车来聚类:
mov['aux']=mov['car']+" - "+mov['operation']
mov['cluster']=(mov.aux != mov.aux.shift()).cumsum()
3-最后,我可以按此簇ID进行分组,并获得最小值“ in”值和最大值“ out”值:
hist_mov=mov.groupby(['cluster','car','operation']).agg({'in':'min',
'out':'max'}).reset_index().copy()