gpt4 book ai didi

python - 有效计算 Pandas 的滚动时间差

转载 作者:太空狗 更新时间:2023-10-30 00:36:05 24 4
gpt4 key购买 nike

我有一个 pandas 面板,我正在尝试计算一个人在每个阶段花费的时间。为了更好地理解这一点,我的数据集如下:

group       date    stage  
A 2014-01-01 one
A 2014-01-03 one
A 2014-01-04 one
A 2014-01-05 two
B 2014-01-02 four
B 2014-01-06 five
B 2014-01-10 five
C 2014-01-03 two
C 2014-01-05 two

我正在计算阶段持续时间以提供:

 group       date    stage  dur
A 2014-01-01 one 0
A 2014-01-03 one 2
A 2014-01-04 one 3
A 2014-01-05 two 0
B 2014-01-02 four 0
B 2014-01-06 five 0
B 2014-01-10 five 4
C 2014-01-03 two 0
C 2014-01-05 two 2

我在下面使用的方法非常慢。关于更快的方法有什么想法吗?

df['stage_duration'] = df.groupby(['group', 'stage']).date.apply(lambda y: (y - y.iloc[0])).apply(lambda y:y / np.timedelta64(1, 'D')))

最佳答案

根据你的代码(你的groupby/apply),看起来(尽管你的例子......但也许我误解了你想要什么然后Andy所做的是最好的主意)你在您的实际数据中使用的是 datetime64 dtype 而不是 integer dtype 的“日期”列。此外,您似乎想要计算从给定 group/stage 的第一次观察开始测量的天数变化。我认为这是一组更好的示例数据(如果我正确理解您的目标):

>>> df

group date stage dur
0 A 2014-01-01 one 0
1 A 2014-01-03 one 2
2 A 2014-01-04 one 3
3 A 2014-01-05 two 0
4 B 2014-01-02 four 0
5 B 2014-01-06 five 0
6 B 2014-01-10 five 4
7 C 2014-01-03 two 0
8 C 2014-01-05 two 2

鉴于您应该通过在应用之后以矢量化方式除以 timedelta64 来仅修改您的应用(正如 Jeff 在他的评论中建议的那样)来获得一些加速(或者您可以这样做它在申请中):

>>> df['dur'] = df.groupby(['group','stage']).date.apply(lambda x: x - x.iloc[0])
>>> df['dur'] /= np.timedelta64(1,'D')
>>> df

group date stage dur
0 A 2014-01-01 one 0
1 A 2014-01-03 one 2
2 A 2014-01-04 one 3
3 A 2014-01-05 two 0
4 B 2014-01-02 four 0
5 B 2014-01-06 five 0
6 B 2014-01-10 five 4
7 C 2014-01-03 two 0
8 C 2014-01-05 two 2

但如果您的数据按组、阶段、日期顺序排列,您也可以避免 groupby/apply。每个 ['group','stage'] 分组的第一个日期发生在组更改或阶段更改时。所以我认为您可以执行以下操作:

>>> beg = (df.group != df.group.shift(1)) | (df.stage != df.stage.shift(1))
>>> df['dur'] = (df['date'] - df['date'].where(beg).ffill())/np.timedelta64(1,'D')
>>> df

group date stage dur
0 A 2014-01-01 one 0
1 A 2014-01-03 one 2
2 A 2014-01-04 one 3
3 A 2014-01-05 two 0
4 B 2014-01-02 four 0
5 B 2014-01-06 five 0
6 B 2014-01-10 five 4
7 C 2014-01-03 two 0
8 C 2014-01-05 two 2

说明:注意 df['date'].where(beg) 创建的内容:

>>> beg = (df.group != df.group.shift(1)) | (df.stage != df.stage.shift(1))
>>> df['date'].where(beg)

0 2014-01-01
1 NaT
2 NaT
3 2014-01-05
4 2014-01-02
5 2014-01-06
6 NaT
7 2014-01-03
8 NaT

然后我填充这些值并在“日期”列中取差值。

编辑:正如 Andy 指出的,您还可以使用 transform:

>>> df['dur'] = df.date - df.groupby(['group','stage']).date.transform(lambda x: x.iloc[0])
>>> df['dur'] /= np.timedelta64(1,'D')

group date stage dur
0 A 2014-01-01 one 0
1 A 2014-01-03 one 2
2 A 2014-01-04 one 3
3 A 2014-01-05 two 0
4 B 2014-01-02 four 0
5 B 2014-01-06 five 0
6 B 2014-01-10 five 4
7 C 2014-01-03 two 0
8 C 2014-01-05 two 2

速度:我使用具有 400,000 个观察值的类似数据框对这两种方法进行计时:

应用方法:

1 loops, best of 3: 18.3 s per loop

非应用方法:

1 loops, best of 3: 1.64 s per loop

所以我认为避免应用可以显着加快速度

关于python - 有效计算 Pandas 的滚动时间差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23796191/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com