在数据帧内的数据子集上计算python中的diff()

时间:2015-01-22 16:42:22

标签: python multiple-columns timedelta

我是Python新手,来自SAS。我想在连续行之间计算滞后变量(使用diff()的时间差),但我想在每次遇到新个体时重新启动该过程。在SAS中,这是使用dif()或lag()使用by-command完成的。使用Python有类似的方法吗?

以下是我希望数据的样子(每当我遇到PIT的新值时,请注意缺少的数据):

PIT Receiver    tottime     Lag
1   1   2015-01-21 12:00:00 
1   1   2015-01-21 12:00:05 5
1   1   2015-01-21 12:00:20 15
1   1   2015-01-21 12:00:30 10
1   1   2015-01-21 12:00:35 5
1   2   2015-01-22 12:00:35 86400
1   2   2015-01-22 12:00:50 15
1   2   2015-01-22 12:00:55 5
1   2   2015-01-22 12:01:05 10
1   2   2015-01-22 12:01:10 5
2   1   2015-01-12 12:01:10 
2   1   2015-01-12 12:01:15 5
2   2   2015-01-12 12:01:20 5
2   2   2015-01-12 12:01:25 5
2   2   2015-01-12 12:01:30 5

我尝试使用此代码:

Clean['tottime']=pd.to_datetime(Clean.tottime.values)   #Convert tottime to     datetime value
tindex=Clean.tottime.values                             #Create vector of time values that will become part of a multi-index
arrays = [Clean.PIT.values,tIndex]                      # Define arrays object, which contains both levels of the multi-index

index = pd.MultiIndex.from_arrays(arrays, names = ['PIT','tottime'])                # declare multi level index
Clean.index = index

Clean['lag'] = Clean.tottime.diff()                                     #    calculated difference in tottime between rows
Clean['lag'] = Clean['lag']/np.timedelta64(1,'s')                       #This converts 'lag' to a numeric (float64) value

但是这会产生类似这样的东西(即在第一行上工作,但后来不能识别新的PIT值):

PIT Receiver    tottime    Lag
1   1   2015-01-21 12:00:00 
1   1   2015-01-21 12:00:05 5
1   1   2015-01-21 12:00:20 15
1   1   2015-01-21 12:00:30 10
1   1   2015-01-21 12:00:35 5
1   2   2015-01-22 12:00:35 86400
1   2   2015-01-22 12:00:50 15
1   2   2015-01-22 12:00:55 5
1   2   2015-01-22 12:01:05 10
1   2   2015-01-22 12:01:10 5
2   1   2015-01-12 12:01:10 -864000
2   1   2015-01-12 12:01:15 5
2   2   2015-01-12 12:01:20 5
2   2   2015-01-12 12:01:25 5
2   2   2015-01-12 12:01:30 5

所以它没有在新的PIT上重置,我得到一个很大的负数(前10天)。最终我希望能够在PIT和Receiver上执行此操作。但是现在的挑战是在整个时间内迭代此过程,按PIT分组。有关如何做到这一点的任何建议吗?

此外,我怀疑这是常见问题的一个子集(通过处理),但我不知道如何用Python语言来表达问题,所以我没有在StackOverflow网站上找到它们。任何指导都将不胜感激。

谢谢!

2 个答案:

答案 0 :(得分:0)

执行此操作的一种方法是使用pandas groupby()功能。

这是一种稍微麻烦的方法,因为我没有您的代码,但您可以尝试以下操作,假设您的DataFrame格式与您显示的格式相同,但没有lag列。

首先,创建一个函数diff_func,该函数将应用于groupby对象。

def diff_func(df):
    return df.diff()

然后使用groupby()

Clean['Lag'] = Clean.groupby('PIT')['tottime'].apply(diff_func)

上述行基本上按Clean列对PIT进行分组,告诉pandas将该函数应用于列tottime,然后将其转储到新列Lag中。

答案 1 :(得分:0)

所以,只要你与前一行有不同的PIT,你就会说?这很简单:

df.loc[df.PIT != df.PIT.shift(1), 'Lag'] = 0