В фрейме данных pandas с показаниями для нескольких систем, как я могу рассчитать средние значения за день и выбрать самое последнее среднее значение для каждой системы

#python #pandas #date #dataframe #calculation

#python #pandas #Дата #фрейм данных #расчет

Вопрос:

Я импортировал свой набор данных в фрейм данных pandas. Каждая строка представляет собой одно значение (амплитуду) из определенной системы (id) с определенной отметкой времени (time_stamp). Из каждой системы есть несколько показаний.

Я хотел бы выбрать самое последнее среднее значение за день для каждой системы.

Это пример моего набора данных:

 df.head(6)

                 time_stamp     amplitude
id      
id1     2018-06-19 00:36:00     16163.1
id1     2018-06-19 01:19:00     16399.7
id1     2018-06-19 01:24:00     16463.3
id1     2018-06-19 03:51:00     16139.4
id2     2018-03-17 03:41:00     11886.0
id2     2018-03-17 03:41:00     12293.6
  

Столбец с отметками времени был преобразован в pd.TimeStamp:

 df.dtypes

time_stamp        datetime64[ns]
amplitude         float64
dtype: object
  

Я начал с вычисления среднего значения за день для каждой системы.

Для этого я заменил временные метки датами, сгруппировал строки по системному идентификатору (индексу) и рассчитал среднее значение для каждой даты. Это создает фрейм данных с MultiIndex [‘id’, ‘date’]

 av = df.copy()

# work with dates rather than time stamps
av['date'] = av.time_stamp.dt.date
av.drop('time_stamp', axis=1, inplace=True)

# calculate daily means for each system
av = av.groupby([av.index,'date']).mean()
av
                    amplitude
id      date    
id1     2018-03-17  13923.500
        2018-04-17  14130.325
        2018-12-22  13532.650
id2     2018-03-17  12234.720
        2018-04-17  12367.050
id3     2018-06-19  16291.375
  

На этом этапе я застрял.

Может кто-нибудь, пожалуйста, предложить, как я мог бы создать новый фрейм данных с самыми последними средними значениями для каждой системы. Что-то вроде этого:

             date     amplitude
id      
id1     2018-12-22  13532.650
id2     2018-04-17  12367.050
id3     2018-06-19  16291.375
  

Спасибо

Ответ №1:

Используйте Index.get_level_values с Index.duplicated , инвертируя маску по ~ и фильтруя по boolean indexing :

 print (df)
             time_stamp  amplitude
id                                
id1 2018-06-19 00:36:00    16163.1
id1 2018-06-18 01:19:00    16399.7
id1 2018-06-18 01:24:00    16463.3
id1 2018-06-20 03:51:00    16139.4
id2 2018-03-17 03:41:00    11886.0
id2 2018-03-17 03:41:00    12293.6

#simplfying solution
av = df.groupby([df.index, df['time_stamp'].dt.date.rename('date')]).mean()
#alternative
#av = df.groupby([df.index, df['time_stamp'].dt.floor('d').rename('date')]).mean()
av = av[~av.index.get_level_values('id').duplicated(keep='last')]
print (av)
                amplitude
id  date           
id1 2018-06-20    16139.4
id2 2018-03-17    12089.8
  

При преобразовании MultiIndex в столбцы используйте DataFrame.drop_duplicates :

 av = df.groupby([df.index, df['time_stamp'].dt.date.rename('date')]).mean().reset_index()

av = av.drop_duplicates('id', keep='last')
print (av)
    id        date  amplitude
2  id1  2018-06-20    16139.4
3  id2  2018-03-17    12089.8
  

Комментарии:

1. Ваше решение работает — спасибо — мне просто нужно убедиться, что 2-й уровень индекса (даты) отсортирован