首页 > 解决方案 > DataFrame行和上一行计算

问题描述

我有一个这样的df:

ID      Category      Event_Time
A          X              12:00
B          X              12:05
B          X              12:05
C          X              12:08
D          X              12:10
D          X              12:10        
E          Y              12:15

我正在尝试计算当前 ID 和先前 ID 的事件时间之间的差异。例如:

ID      Category      Event_Time    Difference
A          X              12:00         NA
B          X              12:05        :05
B          X              12:05        :05
C          X              12:08        :03
D          X              12:10        :02
D          X              12:10        :02 
E          Y              12:15         NA

有几个问题。为了产生差异,行操作之间的Category必须匹配。另外,存在多行ID相同,因此Event_Time相同的情况,但仍然必须计算前一个ID之间的差异。

我有一个 for 循环,基本上是这样的:

unique_id = df.ID.unique()
difference_dict = {}
for i in range (1,len(unique_ID)):
   if current category = previous category
        difference = event_time[i] - event_time[i-1]
    else:
        difference = na
    difference_dict[unique_id[i]] = difference

现在使用数据字典来存储信息。

我发现 for 循环很慢,有人有更强大的解决方案吗?

标签: pythonpandasdataframe

解决方案


用于drop_duplicates删除每个 ID 的重复项,然后用于Series.diff获取差异。最后我们转发填充(ffill):

# convert Event_Time to datetime, so we can make calculations
df['Event_Time'] = pd.to_datetime(df['Event_Time'])

categorys = df['Category'].shift().eq(df['Category'])
df['Difference'] = df.drop_duplicates('ID')['Event_Time'].diff()
df['Difference'] = df.groupby('Category')['Event_Time'].ffill().where(categorys)

# get Event_Time back in correct format
df['Event_Time'] = df['Event_Time'].dt.strftime('%H:%M')

  ID Category Event_Time          Difference
0  A        X      12:00                 NaT
1  B        X      12:05 2020-04-28 12:05:00
2  B        X      12:05 2020-04-28 12:05:00
3  C        X      12:08 2020-04-28 12:08:00
4  D        X      12:10 2020-04-28 12:10:00
5  D        X      12:10 2020-04-28 12:10:00
6  E        Y      12:15                 NaT

推荐阅读