Как преобразовать Azure столбец Длительность отчета резервного копирования в Дата и время с десятичными числами - PullRequest
1 голос
/ 11 июля 2020

Столбец «Продолжительность» в отчете об облачном резервном копировании Azure кажется имеет забавный формат времени (десятичное после часа и после минуты). Не могли бы вы помочь округлить часть часа, минуты и секунды, чтобы столбец был в часах?

1.05:27:39.9470724
21:17.7
21:41.4
1.02:42:37.1136811
21:17.2

Я попытался отформатировать часть микросекунд, но не уверен, как обойти эту десятичную часть в часах. Счастлив просто исключить эти десятичные дроби.

appended_data['Duration'] = pd.to_datetime(appended_data['Duration'], format='%H:%M:%S.%f')
ValueError: time data '1.05:27:39.9470724' does not match format '%H:%M:%S.%f' (match)
appended_data['Backup Size'] = appended_data['Backup Size'].str.replace('MB','')
appended_data['DurationFixed'] = pd.to_timedelta(df['Duration'].str.split(':',expand=True)\
                    .stack()\
                    .astype(float)\
                    .round()\
                    .astype(int).astype(str).unstack(1).fillna('00').agg(':'.join,axis=1),
               unit='s')
appended_data['DurationHours'] = appended_data['DurationFixed'] / np.timedelta64(1,'h')



appended_data['Duration']
1    04:01:22.7756139
1    03:31:17.0678262
1    04:41:32.7253765
1    03:11:18.3396588
1    04:51:20.2017034
           ...       
1    02:21:17.8554095
1    02:21:19.5547075
1    03:41:23.8876812
1    02:21:32.5529160
1    02:01:20.3247238


appended_data['DurationFixed']
1   02:01:20
1   02:01:20
1   02:01:20
1   02:01:20
1   02:01:20
      ...   
1   02:01:20
1   02:01:20
1   02:01:20
1   02:01:20
1   02:01:20

Спасибо

MM

Ответы [ 2 ]

1 голос
/ 14 июля 2020

На основании анализа данных могу сделать вывод, что десятичный разряд в секции hh на самом деле - дни. Пример 2.4: 30: 30 = 2 дня, 4 часа, 30 минут, 30 сек c.

def cleanhours(x):
    hms=x.split(":")
    dh=hms[0].split(".")
    if len(dh)>1:
        hms[0]=str(int(dh[-1])+24*int(dh[-2]))
    hms[2] = hms[2].split(".")[0]
    return int(hms[0])+int(hms[1])/60.0+int(hms[2])/3600.0
#     return ":".join(hms)
0 голосов
/ 11 июля 2020

Похоже на странную ошибку, поскольку я никогда не видел журналов из azure, подобных этой - в любом случае, если нет встроенного метода для обработки таких данных, нам нужно будет разобрать его вручную.

Мы разделим на :, а затем округлим числа перед воссозданием строки дельты времени.

Я должен быть ясным и сказать, что это не настоящее исправление, поскольку вам нужно указать, что такое 1.05, это 1 час и x минут?

если вас не волнует приведенное выше, то ниже должно работать.

Метод 1 Нет точности, строка форматирование.

print(df)

             Duration
0  1.05:27:39.9470724
1             21:17.7
2             21:41.4
3  1.02:42:37.1136811
4             21:17.2
df['DurationFixed'] = pd.to_timedelta(df['Duration'].str.split(':',expand=True)\
                    .stack()\
                    .astype(float)\
                    .round()\
                    .astype(int).astype(str).unstack(1).fillna('00').agg(':'.join,axis=1),
               unit='s')
                

print(df)

           Duration DurationFixed
0  1.05:27:39.9470724      01:27:40
1             21:17.7      21:18:00
2             21:41.4      21:41:00
3  1.02:42:37.1136811      01:42:37
4             21:17.2      21:17:00

если вы хотите только часы, вы можете преобразовать его, используя np.timedelta64

import numpy as np

df['DurationFixed'] / np.timedelta64(1,'h')
0     1.461111
1    21.300000
2    21.683333
3     1.710278
4    21.283333
Name: DurationFixed, dtype: float64

Метод 2 с большей точностью.

если ваши данные находятся в том же формате - например, Hours : Minutes : Seconds

, мы могли бы складывать и применять кумулятивный счетчик и отображать поля метаданных для использования нашего pd.to_timedelta на уровне ряда.

s = df['Duration'].str.split(':',expand=True)\
                    .stack()\
                    .astype(float).to_frame('time_delta')

print(s)

     time_delta
0 0   1.050000
  1  27.000000
  2  39.947072
1 0  21.000000
  1  17.700000
2 0  21.000000
  1  41.400000
3 0   1.020000
  1  42.000000
  2  37.113681
4 0  21.000000
  1  17.200000
s['metadata'] = s.groupby(level=0).cumcount().map({0 : 'h', 1 : 'm', 2 : 's' })

print(s)

    time_delta metadata
0 0   1.050000        h
  1  27.000000        m
  2  39.947072        s
1 0  21.000000        h
  1  17.700000        m
2 0  21.000000        h
  1  41.400000        m
3 0   1.020000        h
  1  42.000000        m
  2  37.113681        s
4 0  21.000000        h
  1  17.200000        m

Наконец, мы используем apply на уровне строки, чтобы преобразовать каждую строку в свой формат воспроизведения и округлить до ближайших n секунд. Я выбрал 10.

df['DurationPrecise'] = s.apply(lambda x : pd.to_timedelta(x.time_delta,
                                x.metadata,errors='coerce'),axis=1)\          
              .groupby(level=0).sum().dt.round('10s')


print(df)

             Duration DurationFixed DurationPrecise
0  1.05:27:39.9470724      01:27:40        01:30:40
1             21:17.7      21:18:00        21:17:40
2             21:41.4      21:41:00        21:41:20
3  1.02:42:37.1136811      01:42:37        01:43:50
4             21:17.2      21:17:00        21:17:10
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...