我是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网站上找到它们。任何指导都将不胜感激。
谢谢!
答案 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