0
votes

I have a DataFrame of timestamps. I am trying to update a slice of this dataframe using .loc. When I add datetime to the slice independently, the return is as expected.

However, when I try to assign it to the dataframe so that it updates inplace, the formatting returns as a UNIX Timestamp (i.e.1591003030000000000). I am wondering how to fix this so that the dataframe shows all datetime objects.

import numpy as np
import pandas as pd
import datetime
import itertools

num_trucks=8
year,month,day=datetime.datetime.now().year,datetime.datetime.now().month,datetime.datetime.now().day
digging_time=210
loaded_travel=600
dumping_time=90
unloaded_travel=500
full_cycle = digging_time+loaded_travel+dumping_time+unloaded_travel

crib_loc=0.4
dump_to_crib=int((1-crib_loc)*unloaded_travel)
dig_to_crib=int(0.4*unloaded_travel)

trucks=['Truck'+str(i) for i in range(1,num_trucks+1)]

df=pd.DataFrame(columns=['truck','queue_dig','start_dig','stop_dig','start_dump','stop_dump','pass_crib'],index=range(0,int(43200/full_cycle)*num_trucks))

def fill_cycle(df):
    while len(df.dropna()) < num_trucks:
        if len(df.dropna()) == 0:
            start = pd.Timestamp(year,month,day,6,30)
            df.at[0,'truck']='Truck1'
            df.at[0,'queue_dig']=start
            df.at[0,'start_dig']=start
            df.at[0,'stop_dig']=df.at[0,'start_dig']+pd.Timedelta(seconds=digging_time)
            df.at[0,'start_dump']=df.at[0,'stop_dig']+pd.Timedelta(seconds=loaded_travel)
            df.at[0,'stop_dump']=df.at[0,'start_dump']+pd.Timedelta(seconds=dumping_time)
            df.at[0,'pass_crib']=df.at[0,'stop_dump']+pd.Timedelta(seconds=dump_to_crib)
        else:
            #last row entered
            lr=df.dropna(how='all').index[-1]
            #next truck to go
            next_truck=[truck for truck in trucks if truck not in df.dropna(how='all')['truck'].values][0]
            df.at[lr+1,'truck']=next_truck
            df.at[lr+1,'queue_dig']=start
            df.at[lr+1,'start_dig']=df.at[lr,'stop_dig']
            df.at[lr+1,'stop_dig']=df.at[lr+1,'start_dig']+pd.Timedelta(seconds=digging_time)
            df.at[lr+1,'start_dump']=df.at[lr+1,'stop_dig']+pd.Timedelta(seconds=loaded_travel)
            df.at[lr+1,'stop_dump']=df.at[lr+1,'start_dump']+pd.Timedelta(seconds=dumping_time)
            df.at[lr+1,'pass_crib']=df.at[lr+1,'start_dump']+pd.Timedelta(seconds=dump_to_crib)

    for truck in itertools.cycle(trucks):
        this_truck=max(df[df['truck']==truck]['stop_dump'])
        lr=df.dropna(how='all').index[-1]
        if df.at[lr,'stop_dig'] > pd.Timestamp(year,month,day,18,00,00) - pd.Timedelta(seconds=full_cycle):
            break
        df.at[lr+1,'truck']=truck
        last_truck=df.at[lr,'stop_dig']
        df.at[lr+1,'queue_dig']=this_truck + pd.Timedelta(seconds=unloaded_travel)
        if df.at[lr+1,'queue_dig'] < last_truck:
            df.at[lr+1,'start_dig']=df.at[lr,'stop_dig']
        else:
            df.at[lr+1,'start_dig']=df.at[lr+1,'queue_dig']
        df.at[lr+1,'stop_dig']=df.at[lr+1,'start_dig']+pd.Timedelta(seconds=digging_time)
        df.at[lr+1,'start_dump']=df.at[lr+1,'stop_dig']+pd.Timedelta(seconds=loaded_travel)
        df.at[lr+1,'stop_dump']=df.at[lr+1,'start_dump']+pd.Timedelta(seconds=dumping_time)
        df.at[lr+1,'pass_crib']=df.at[lr+1,'start_dump']+pd.Timedelta(seconds=dump_to_crib)

    df.dropna(inplace=True)

fill_cycle(df)

#this is the important part

df.loc[(df.index>100)&(df['truck']=='Truck4'),df.columns.drop('truck')]=df.loc[(df.index>100)&(df['truck']=='Truck4'),df.columns.drop('truck')]+pd.Timedelta(seconds=500)

df.loc[(df.index>100)&(df['truck']=='Truck4'),df.columns.drop('truck')]
could you provide a working minimal reproducible example? - FObersteiner
I have added in the code I am having trouble with. I tried to recreate it more simply, but a mock data frame would not recreate the issue. Thanks - lambda