Отрицательная продолжительность времени в Пандах - PullRequest
0 голосов
/ 25 сентября 2019

У меня есть набор данных с двумя столбцами: фактическое время и обещанное время (представляющие фактическое и обещанное время начала какого-либо процесса).

Например:

import pandas as pd
example_df = pd.DataFrame(columns = ['Actual Time', 'Promised Time'],
                 data = [
                     ('2016-6-10 9:00', '2016-6-10 9:00'),
                     ('2016-6-15 8:52', '2016-6-15 9:52'),
                     ('2016-6-19 8:54', '2016-6-19 9:02')]).applymap(pd.Timestamp)

Итак, как мы видим, sometimes Actual Time = Promised Time, но есть также случаи, когда Actual Time < Promised Time.

Я определил столбец, который показывает разницу между этими двумя столбцами (example_df['Actual Time']-example_df['Promised Time']), но проблема в том, что для третьей строки он вернул -1 day +23:52:00 вместо - 00:08:00.

Ответы [ 3 ]

1 голос
/ 25 сентября 2019

Я предполагаю, что ваш фрейм данных уже в datetime dtype.abs прекрасно работает

Без abs

df['Actual Time'] - df['Promised Time']

Out[526]:
0            00:00:00
1   -1 days +23:00:00
2   -1 days +23:52:00
dtype: timedelta64[ns]

С abs

abs(df['Promised Time'] - df['Actual Time'])

Out[529]:
0   00:00:00
1   01:00:00
2   00:08:00
dtype: timedelta64[ns]
1 голос
/ 25 сентября 2019

Образец :

print (df)
       Actual Time   Promised Time
0   2016-6-10 9:00  2016-6-10 9:00
1  2016-6-15 10:52  2016-6-15 9:52 <- changed datetimes
2   2016-6-19 8:54  2016-6-19 9:02

def format_timedelta(x):
    ts = x.total_seconds()
    if ts >= 0:
        hours, remainder = divmod(ts, 3600)
        minutes, seconds = divmod(remainder, 60)
        return ('{}:{:02d}:{:02d}').format(int(hours), int(minutes), int(seconds)) 
    else:
        hours, remainder = divmod(-ts, 3600)
        minutes, seconds = divmod(remainder, 60)
        return ('-{}:{:02d}:{:02d}').format(int(hours), int(minutes), int(seconds)) 

Сначала создайте datetime с:

df['Actual Time'] = pd.to_datetime(df['Actual Time'])
df['Promised Time'] = pd.to_datetime(df['Promised Time'])

А затем timedeltas:

df['diff'] = (df['Actual Time'] - df['Promised Time'])

Есликонвертировать отрицательные таймдельты в секунды на Series.dt.total_seconds это работает хорошо:

df['diff1'] = df['diff'].dt.total_seconds()

Но если вы хотите, чтобы отрицательные таймдельты в строковом представлении были возможны с пользовательской функцией, потому что strftime для таймделт этоеще не реализовано:

df['diff2'] = df['diff'].apply(format_timedelta)
print (df)
          Actual Time       Promised Time              diff   diff1     diff2
0 2016-06-10 09:00:00 2016-06-10 09:00:00          00:00:00     0.0   0:00:00
1 2016-06-15 10:52:00 2016-06-15 09:52:00          01:00:00  3600.0   1:00:00
2 2016-06-19 08:54:00 2016-06-19 09:02:00 -1 days +23:52:00  -480.0  -0:08:00
0 голосов
/ 25 сентября 2019

Результат разницы равен timedelta типу, который по умолчанию имеет формат ns.

Вам необходимо изменить тип результата на нужный вам формат:

import pandas as pd

df=pd.DataFrame(data={
'Actual Time':['2016-6-10 9:00','2016-6-15 8:52','2016-6-19 8:54'],
'Promised Time':['2016-6-10 9:00','2016-6-15 9:52','2016-6-19 9:02']
},dtype='datetime64[ns]')

# here you need to add the `astype` part and to determine the unit you want
df['diff']=(df['Actual Time']-df['Promised Time']).astype('timedelta64[m]')


Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...