Как найти пробелы в датах с помощью панд - PullRequest
0 голосов
/ 14 ноября 2018

У меня есть набор данных, который показывает производительность устройства в месяц.Вот как выглядят данные

device, date, performance
   1  , 06/16, 50.4
   1  , 07/16, 54
   1  , 08/16, 6
   1  , 09/17, 67
   1  , 10/17, 56
   2  , 01/12, 34
       ....

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

device, start, end
 1    ,  06/16, 08/16
 1    ,  09/17, 10/17
     ....

Как я могу создать это с помощью панд?

Ответы [ 2 ]

0 голосов
/ 15 ноября 2018

Чтобы быть более поучительным, я немного расширил ваши исходные данные, чтобы они содержит полные наборы 5 чтений для 2 устройств. Я также решил изменить столбец date на истинные даты.

Концепция основана на группировании по device, а затем генерации даты начала / окончания каждой группы.

Сценарий, генерирующий периоды начала / окончания, может быть следующим:

import pandas as pd

# Source data
df = pd.DataFrame(data={ 'device': [ 1, 1, 1, 1, 1, 2, 2, 2, 2, 2 ],
    'date': [ '06/16', '07/16', '08/16', '09/17', '10/17',
        '03/16', '04/16', '11/16', '12/16', '01/17' ],
    'performance': [ 50.4, 54, 6, 67, 56, 50, 45, 30, 72.3, 42 ] })
# Convert date to true dates
df.date = pd.to_datetime(df.date, format='%m/%y')
grp = df.groupby(by='device')
# Starts of periods
st = grp.apply(lambda x: x.date[x.date - pd.DateOffset(months = 1)
    != x.date.shift()]).reset_index(level=1,drop=True)
# Ends of periods
en = grp.apply(lambda x: x.date[x.date + pd.DateOffset(months = 1)
    != x.date.shift(-1)]).reset_index(level=1,drop=True)
# Result - concat start / end dates
res = pd.concat([st, en], axis=1).reset_index()
# Set column names
res.columns = ['device', 'start', 'end']

Результат:

   device      start        end
0       1 2016-06-01 2016-08-01
1       1 2017-09-01 2017-10-01
2       2 2016-03-01 2016-04-01
3       2 2016-11-01 2017-01-01
0 голосов
/ 14 ноября 2018

Вы можете создавать серии с одним и тем же номером в течение нескольких месяцев подряд или на одном устройстве.Для этого вы можете использовать shift и добавить месяц с DateOffset, чтобы проверить, находится ли следующая строка с интервалом в месяц.Используйте cumsum для увеличения значения для каждой новой группы.Сначала вам нужно столбец «дата» как datetime в серии:

ser_date = pd.to_datetime(df['date'],format='%m/%y')
ser_group = ((((ser_date.shift() + pd.DateOffset(months=1)) != ser_date) | #month apart
              (df.device.diff() != 0)) # different device
              .cumsum()) #increment value for each group

Теперь вы можете использовать groupby для ser_group, join для first и last длякаждая группа, такая как:

g_df = df.groupby(ser_group) #grouped data
df_new = (g_df['device','date'].first() #first of each group
          .join(g_df['date'].last(),rsuffix='_') #joined with last of each group
          .rename(columns={'date':'start','date_':'end'})) #rename column start/end

print (df_new)
   device   start     end
1       1   06/16   08/16
2       1   09/17   10/17
3       2   01/12   01/12
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...