使用.shift()根据两个条件语句创建熊猫列

时间:2020-03-01 21:56:50

标签: python pandas dataframe

我有一个用户事件的熊猫数据框,按user_id和datetime升序排列。我想计算基于每个用户的事件之间的时间差,并且我希望每个用户在df['tdelta']中的第一个事件记录都为空值。以下是快速操作,但是如果user_id更改,则不会使条目无效。

df['tdelta'] = df['time'] - df['time'].shift()

这是我当前的解决方案,但是太慢了。

def get_tdelta(df, tdelta_column="tdelta"):
    df[tdelta_column] = np.NaN
    df[tdelta_column] = df[tdelta_column].astype('datetime64[ns]')
    for cid, pid, ct, pt, idx in zip(df['user_id'], df['user_id'].shift(), df['time'], df['time'].shift(), df.index):
        if cid==pid:
            df.loc[idx, tdelta_column] = ct - pt
        else:
            pass
    return event_dataframe

event_df = get_tdelta(event_df)

我想有一个与以下类似的快速解决方案,但是我对如何完成它有些困惑。我已经添加了以下代码的错误,并且我理解为什么会得到它,但是我只是在寻找一种更快的方法来实现它

df['tdelta'] = df['time'] - df['time'].shift() if (df['user_id'] == df['user_id'].shift()) else np.NaN
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

以下是演示数据框前后的演示:

data = {'user_id' : [1, 1, 1, 2, 2, 2],
        'event_id' : [2, 2, 3, 2, 3, 3],
        'time' : ['2020-02-27 12:31:00', '2020-02-27 12:32:00', '2020-02-27 12:32:30', '2020-02-27 02:22:00', '2020-02-27 02:27:00', '2020-03-01 02:39:00']}
df = pd.DataFrame(data)
df.time = df.time.astype('datetime64[ns]')

    user_id event_id    time                   
0   1       2           2020-02-27 12:31:00    
1   1       2           2020-02-27 12:32:00     
2   1       3           2020-02-27 12:32:30     
3   2       2           2020-02-27 02:22:00     
4   2       3           2020-02-27 02:27:00     
5   2       3           2020-03-01 02:39:00     
data = {'user_id' : [1, 1, 1, 2, 2, 2],
        'event_id' : [2, 2, 3, 2, 3, 3],
        'time' : ['2020-02-27 12:31:00', '2020-02-27 12:32:00', '2020-02-27 12:32:30', '2020-02-27 02:22:00', '2020-02-27 02:27:00', '2020-03-01 02:39:00'],
        'tdelta' : ['NaT', '0 days 00:01:00', '0 days 00:00:30', 'NaT', '0 days 00:05:00', '3 days 00:12:00']}
df = pd.DataFrame(data)
df.time = df.time.astype('datetime64[ns]')

    user_id event_id    time                    tdelta
0   1       2           2020-02-27 12:31:00     NaT
1   1       2           2020-02-27 12:32:00     0 days 00:01:00
2   1       3           2020-02-27 12:32:30     0 days 00:00:30
3   2       2           2020-02-27 02:22:00     NaT
4   2       3           2020-02-27 02:27:00     0 days 00:05:00
5   2       3           2020-03-01 02:39:00     3 days 00:12:00

1 个答案:

答案 0 :(得分:0)

要计算每个用户的事件之间的时间增量,请按user_id进行分组,然后对组合的数据帧应用移位减法。

然后,通过从索引中删除user_id清理结果并作为新列分配回原始数据帧。每个user_id的第一个事件默认情况下为null (NaN)

df['tdelta'] = df.groupby('user_id') \
  .apply(lambda x: x.time - x.time.shift()) \
  .reset_index(level='user_id', drop=True)