Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何计算数据帧中分组行集合内上一行的差异_Python_Pandas - Fatal编程技术网

Python 如何计算数据帧中分组行集合内上一行的差异

Python 如何计算数据帧中分组行集合内上一行的差异,python,pandas,Python,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

我正在寻找帮助,以解决熊猫中同时出现的分组/行对行差异问题。该问题与此处针对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   
我想计算每个唯一的用户ID-合同参考对与上次提交的时间差

注意:每个用户标识-契约引用对的第一次出现都必须为零(或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
我目前正从R迁移到Pandas,虽然我发现语法令人耳目一新,但当涉及到数据帧上的复杂函数时,我有点不知所措


提前感谢您提供的任何提示

[注意:您的数据似乎与所需的输出不匹配;第二行中没有合同_REF
C
s,即使在您的输出中,我也不明白为什么
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)
产生

>>> 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]

一些解释:从数据帧开始,如

>>> 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]
我们希望将提交日期列从字符串变为实际日期对象:

>>> 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]
然后我们可以按
用户ID
合同参考
进行分组,并选择
提交日期
列:

>>> gs = df.groupby(["USER_ID", "CONTRACT_REF"])["SUBMISSION_DATE"]
>>> gs
<pandas.core.groupby.SeriesGroupBy object at 0xa7af08c>
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]
既然你想用小时来衡量,我们可以除以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
将其指定给框架:

>>> df["TIME_DIFF"] = gs.diff().fillna(0) / pd.datetools.timedelta(hours=1)
我们完成了:

>>> 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]

仅供参考,您也可以用
np.timedelta64(1,'H')
除法,或者用
astype('timedelta64[H]')
代替0.13中的除法,在timedelta64上提供您想要的任何浮点输出格式的转换@Jeff:
np.timedelta64(1,'H')
可以工作,但
astype('timedelta64[H'))
--我需要一个小写的
h
--看起来是截断的,所以我不会得到1.5。哇,我不知道这些groupby对象,看起来非常有用!谢谢DSM-非常有用的解释。你对示例中的错误是正确的。@HarryPalmer:绝对值得阅读文档的部分-使用得当,或者甚至不那么明智;^--
groupby
可以让你的生活更轻松。是的,A型截短,但除法给出了确切的值特征!
>>> 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]