Как вычислить разницу временных меток на основе многоуровневого индекса?

#python #python-3.x #pandas #numpy #dataframe

#python #python-3.x #pandas #numpy #фрейм данных

Вопрос:

У меня есть следующее pandas.DataFrame , и я хотел бы вычислить новый столбец, содержащий timedelta между последовательными временными метками на многоиндексном уровне Timestamp :

 import pandas as pd
import numpy as np
data = {'Timestamp': [12, 12, 12, 22, 22, 22, 44, 44, 66, 102],
        'Customer': ['bmw', 'vw', 'vw', 'bmw', 'vw', 'vw', 'vw', 'vw', 'bmw', 'bmw'],
        'Series': ['series1', 'series1', 'series2', 'series1', 'series1', 'series2', 'series1', 'series2', 'series2', 'series1'],
        'time_delta': [np.nan, np.nan, np.nan, 10, 10, 10, 22, 22, 22, 36]
        }
df = pd.DataFrame(data).set_index(['Timestamp', 'Customer', 'Series'])
  

Столбец time_delta — это желаемый результат, которого я хотел бы достичь. Я несколько борюсь, так как не могу использовать pandas.Series.diff() функцию periods , поскольку они несовместимы. Я хочу выполнить вычисление разности временных меток на Timestamp уровне фрейма данных, но передать результат во все строки этого уровня. Таким образом, для значения первого Timestamp уровня 12 нет предшествующего значения временной метки, поэтому все строки для этой временной метки заполняются np.nan . Для следующей временной метки 22 я могу взять дельту до 12 (что равно 10) и заполнить ее для всех строк временной метки 22.

Ответ №1:

Давайте попробуем извлечь значения уровней и вычислить разницу оттуда:

 df['time_delta'] = df.index.get_level_values('Timestamp')

s = df['time_delta'].diff()
df['time_delta'] = s.where(s>0).ffill()
  

Вывод:

                             time_delta
Timestamp Customer Series             
12        bmw      series1         NaN
          vw       series1         NaN
                   series2         NaN
22        bmw      series1        10.0
          vw       series1        10.0
                   series2        10.0
44        vw       series1        22.0
                   series2        22.0
66        bmw      series2        22.0
102       bmw      series1        36.0