Python 如何利用熊猫找出日期的差距

Python 如何利用熊猫找出日期的差距,python,pandas,Python,Pandas,我有一个数据集,显示每月一台设备的性能。下面是数据的样子 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, 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
     ....

如何使用pandas创建该序列?

您可以在连续月份或相同设备上创建具有相同编号的序列。要执行此操作,您可以使用
shift
并添加一个月,以检查以下行是否相隔一个月。使用
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
现在,您可以在
seru group
上使用
groupby
加入每个组的
第一个
最后一个
,例如:

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

为了更具启发性,我对源数据进行了一些扩展,以便 包含2台设备的全套5个读数。 我还决定将
date
列更改为true dates

该概念基于通过
设备进行分组,然后生成
每个组的开始/结束日期

生成开始/结束时段的脚本可以如下所示:

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