我有一个数据集,可以显示每月设备的性能。这是数据的样子
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
....
如何使用熊猫来创建它?
答案 0 :(得分:3)
连续两个月或使用同一设备时,您可以创建具有相同编号的系列。为此,您可以使用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
答案 1 :(得分:1)
为了更具启发性,我扩展了一点您的源数据,以便
包含2个设备的5个读数的完整集合。
我还决定将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