我正在寻找Pandas中同时分组/行上行差异问题的帮助.问题与R中所述完全相同:如何计算每个组(学生合同)的日期时间之间的时差?
我有这样的数据:
# USER_ID CONTRACT_REF SUBMISSION_DATE
1 1 A 20/6 01:00
2 1 A 20/6 02:00
3 1 B 20/6 03:00
4 4 A 20/6 04:00
5 5 A 20/6 05:00
6 5 B 20/6 06:00
7 7 A 20/6 07:00
8 7 B 20/6 08:00
9 7 B 20/6 09:30
10 7 B 20/6 10:00
Run Code Online (Sandbox Code Playgroud)
我想计算每个唯一USER_ID - CONTRACT_REF对的上一次提交的时间差.
注意:每个USER_ID - CONTRACT_REF对的第一次出现必须为零(或为null).
因此输出应如下所示:
# USER_ID CONTRACT_REF SUBMISSION_DATE TIME_DIFFERENCE
1 1 A 20/6 01:00 0
2 1 A 20/6 02:00 1
3 1 B 20/6 03:00 0
4 4 A 20/6 04:00 0
5 5 A 20/6 05:00 0
6 5 B 20/6 06:00 0
7 7 A 20/6 07:00 0
8 7 A 20/6 08:00 1
9 7 A 20/6 09:30 1.5
10 7 B 20/6 10:00 0
Run Code Online (Sandbox Code Playgroud)
我现在正从R转移到Pandas,虽然我发现语法令人耳目一新,但在涉及数据帧上的复杂函数时,我有点难过.
提前感谢任何提示!
[注意:您的数据似乎与您想要的输出不匹配; C在第二个中没有CONTRACT_REF ,甚至在你的输出中,我不明白为什么5, B行是1而不是0.我假设这些都是你的错误.由于你没有评论,我将使用输出中的数据,因为它会导致更有趣的列.]
我可能会做类似的事情
df["SUBMISSION_DATE"] = pd.to_datetime(df["SUBMISSION_DATE"],dayfirst=True)
gs = df.groupby(["USER_ID", "CONTRACT_REF"])["SUBMISSION_DATE"]
df["TIME_DIFF"] = gs.diff().fillna(0) / pd.datetools.timedelta(hours=1)
Run Code Online (Sandbox Code Playgroud)
哪个产生
>>> df
# USER_ID CONTRACT_REF SUBMISSION_DATE TIME_DIFF
0 1 1 A 2014-06-20 01:00:00 0.0
1 2 1 A 2014-06-20 02:00:00 1.0
2 3 1 B 2014-06-20 03:00:00 0.0
3 4 4 A 2014-06-20 04:00:00 0.0
4 5 5 A 2014-06-20 05:00:00 0.0
5 6 5 B 2014-06-20 06:00:00 0.0
6 7 7 A 2014-06-20 07:00:00 0.0
7 8 7 A 2014-06-20 08:00:00 1.0
8 9 7 A 2014-06-20 09:30:00 1.5
9 10 7 B 2014-06-20 10:00:00 0.0
[10 rows x 5 columns]
Run Code Online (Sandbox Code Playgroud)
一些解释:从数据帧开始
>>> df
# USER_ID CONTRACT_REF SUBMISSION_DATE
0 1 1 A 20/6 01:00
1 2 1 A 20/6 02:00
2 3 1 B 20/6 03:00
3 4 4 A 20/6 04:00
4 5 5 A 20/6 05:00
5 6 5 B 20/6 06:00
6 7 7 A 20/6 07:00
7 8 7 A 20/6 08:00
8 9 7 A 20/6 09:30
9 10 7 B 20/6 10:00
[10 rows x 4 columns]
Run Code Online (Sandbox Code Playgroud)
我们希望将SUBMISSION_DATE列从字符串转换为实际日期对象:
>>> df["SUBMISSION_DATE"] = pd.to_datetime(df["SUBMISSION_DATE"],dayfirst=True)
>>> df
# USER_ID CONTRACT_REF SUBMISSION_DATE
0 1 1 A 2014-06-20 01:00:00
1 2 1 A 2014-06-20 02:00:00
2 3 1 B 2014-06-20 03:00:00
3 4 4 A 2014-06-20 04:00:00
4 5 5 A 2014-06-20 05:00:00
5 6 5 B 2014-06-20 06:00:00
6 7 7 A 2014-06-20 07:00:00
7 8 7 A 2014-06-20 08:00:00
8 9 7 A 2014-06-20 09:30:00
9 10 7 B 2014-06-20 10:00:00
[10 rows x 4 columns]
Run Code Online (Sandbox Code Playgroud)
那么我们就可以通过组USER_ID和CONTRACT_REF,并选择SUBMISSION_DATE栏:
>>> gs = df.groupby(["USER_ID", "CONTRACT_REF"])["SUBMISSION_DATE"]
>>> gs
<pandas.core.groupby.SeriesGroupBy object at 0xa7af08c>
Run Code Online (Sandbox Code Playgroud)
然后我们可以采取每组的差异:
>>> gs.diff()
0 NaT
1 01:00:00
2 NaT
3 NaT
4 NaT
5 NaT
6 NaT
7 01:00:00
8 01:30:00
9 NaT
dtype: timedelta64[ns]
Run Code Online (Sandbox Code Playgroud)
NaT,非时间,是时间的等价物NaN.我们可以填0:
>>> gs.diff().fillna(0)
0 00:00:00
1 01:00:00
2 00:00:00
3 00:00:00
4 00:00:00
5 00:00:00
6 00:00:00
7 01:00:00
8 01:30:00
9 00:00:00
dtype: timedelta64[ns]
Run Code Online (Sandbox Code Playgroud)
而且由于你想要用几小时来衡量一些东西,我们可以将时间分为1小时:
>>> gs.diff().fillna(0) / pd.datetools.timedelta(hours=1)
0 0.0
1 1.0
2 0.0
3 0.0
4 0.0
5 0.0
6 0.0
7 1.0
8 1.5
9 0.0
dtype: float64
Run Code Online (Sandbox Code Playgroud)
将其分配给框架:
>>> df["TIME_DIFF"] = gs.diff().fillna(0) / pd.datetools.timedelta(hours=1)
Run Code Online (Sandbox Code Playgroud)
我们完成了:
>>> df
# USER_ID CONTRACT_REF SUBMISSION_DATE TIME_DIFF
0 1 1 A 2014-06-20 01:00:00 0.0
1 2 1 A 2014-06-20 02:00:00 1.0
2 3 1 B 2014-06-20 03:00:00 0.0
3 4 4 A 2014-06-20 04:00:00 0.0
4 5 5 A 2014-06-20 05:00:00 0.0
5 6 5 B 2014-06-20 06:00:00 0.0
6 7 7 A 2014-06-20 07:00:00 0.0
7 8 7 A 2014-06-20 08:00:00 1.0
8 9 7 A 2014-06-20 09:30:00 1.5
9 10 7 B 2014-06-20 10:00:00 0.0
[10 rows x 5 columns]
Run Code Online (Sandbox Code Playgroud)