Python 3.x 在另一个时间戳之前计算时间戳数量的更快方法

Python 3.x 在另一个时间戳之前计算时间戳数量的更快方法,python-3.x,time-series,Python 3.x,Time Series,我有两个数据帧“train”和“log”。“日志”有日期时间列“time1”,而列车有日期时间列“time2”。对于“train”中的每一行,我想找出“time1”在“time2”之前的计数 我已经用dataframe尝试了apply方法 def log_计数(行): 返回和((日志['user\u id']==行['user\u id'])和(日志['time1']

我有两个数据帧“train”和“log”。“日志”有日期时间列“time1”,而列车有日期时间列“time2”。对于“train”中的每一行,我想找出“time1”在“time2”之前的计数

我已经用dataframe尝试了apply方法

def log_计数(行):
返回和((日志['user\u id']==行['user\u id'])和(日志['time1']<行['time2']))
应用序列(对数计数,轴=1)

这种方法需要花费很长时间。

由于您希望为每个(配对的)
用户id
组执行一次此操作,您可以执行以下操作:

  • log
    中创建一个名为
    is\u log
    的列,该列在
    train
    中为
    1
    ,在
    train
    中为
    0

    log['is_log'] = 1
    train['is_log'] = 0
    
    is\u log
    列将用于跟踪行是否来自
    log
    train

  • 连接
    日志
    序列
    数据帧:

    combined = pd.concat(
        [log.rename(columns=dict(time1="time")), train.rename(columns=dict(time2="time"))],
        axis=0,
        ignore_index=True,
        sort=False,
    )
    
  • 用户id
    时间对组合的
    数据帧进行排序:

    combined = combined.sort_values(by=["user_id", "time"])
    
    所以现在组合的
    看起来像这样:

             time  user_id  is_log
    6  2000-01-17        0       0
    0  2000-03-13        0       1
    1  2000-06-08        0       1
    7  2000-06-25        0       0
    4  2000-07-09        0       1
    8  2000-07-18        0       0
    10 2000-03-13        1       0
    5  2000-04-16        1       0
    3  2000-08-04        1       1
    9  2000-08-17        1       0
    2  2000-10-20        1       1
    
  • 现在,您要查找的计数可以表示为
    is\u log
    列的累积和,按
    用户id
    分组:

    combined["count"] = combined.groupby("user_id")["is_log"].cumsum()
    train = combined.loc[combined["is_log"] == 0]
    
    这是主要思想:计算
    is_log
    列中
    1
    s的数量相当于计算
    log
    中在
    train
    中每次之前出现的次数


比如说,

import numpy as np
import pandas as pd

np.random.seed(2019)


def random_dates(N):
    return np.datetime64("2000-01-01") + np.random.randint(
        365, size=N
    ) * np.timedelta64(1, "D")


N = 5
log = pd.DataFrame({"time1": random_dates(N), "user_id": np.random.randint(2, size=N)})
train = pd.DataFrame(
    {
        "time2": np.r_[random_dates(N), log.loc[0, "time1"]],
        "user_id": np.random.randint(2, size=N + 1),
    }
)

log["is_log"] = 1
train["is_log"] = 0
combined = pd.concat(
    [log.rename(columns=dict(time1="time")), train.rename(columns=dict(time2="time"))],
    axis=0,
    ignore_index=True,
    sort=False,
)
combined = combined.sort_values(by=["user_id", "time"])
combined["count"] = combined.groupby("user_id")["is_log"].cumsum()
train = combined.loc[combined["is_log"] == 0]

print(log)
#        time1  user_id  is_log
# 0 2000-03-13        0       1
# 1 2000-06-08        0       1
# 2 2000-10-20        1       1
# 3 2000-08-04        1       1
# 4 2000-07-09        0       1

print(train)
屈服

         time  user_id  is_log  count
6  2000-01-17        0       0      0
7  2000-06-25        0       0      2
8  2000-07-18        0       0      3
10 2000-03-13        1       0      0
5  2000-04-16        1       0      0
9  2000-08-17        1       0      1

由于您希望对每个(配对的)
user\u id
组执行一次此操作,因此可以执行以下操作:

  • log
    中创建一个名为
    is\u log
    的列,该列在
    train
    中为
    1
    ,在
    train
    中为
    0

    log['is_log'] = 1
    train['is_log'] = 0
    
    is\u log
    列将用于跟踪行是否来自
    log
    train

  • 连接
    日志
    序列
    数据帧:

    combined = pd.concat(
        [log.rename(columns=dict(time1="time")), train.rename(columns=dict(time2="time"))],
        axis=0,
        ignore_index=True,
        sort=False,
    )
    
  • 用户id
    时间对组合的
    数据帧进行排序:

    combined = combined.sort_values(by=["user_id", "time"])
    
    所以现在组合的
    看起来像这样:

             time  user_id  is_log
    6  2000-01-17        0       0
    0  2000-03-13        0       1
    1  2000-06-08        0       1
    7  2000-06-25        0       0
    4  2000-07-09        0       1
    8  2000-07-18        0       0
    10 2000-03-13        1       0
    5  2000-04-16        1       0
    3  2000-08-04        1       1
    9  2000-08-17        1       0
    2  2000-10-20        1       1
    
  • 现在,您要查找的计数可以表示为
    is\u log
    列的累积和,按
    用户id
    分组:

    combined["count"] = combined.groupby("user_id")["is_log"].cumsum()
    train = combined.loc[combined["is_log"] == 0]
    
    这是主要思想:计算
    is_log
    列中
    1
    s的数量相当于计算
    log
    中在
    train
    中每次之前出现的次数


比如说,

import numpy as np
import pandas as pd

np.random.seed(2019)


def random_dates(N):
    return np.datetime64("2000-01-01") + np.random.randint(
        365, size=N
    ) * np.timedelta64(1, "D")


N = 5
log = pd.DataFrame({"time1": random_dates(N), "user_id": np.random.randint(2, size=N)})
train = pd.DataFrame(
    {
        "time2": np.r_[random_dates(N), log.loc[0, "time1"]],
        "user_id": np.random.randint(2, size=N + 1),
    }
)

log["is_log"] = 1
train["is_log"] = 0
combined = pd.concat(
    [log.rename(columns=dict(time1="time")), train.rename(columns=dict(time2="time"))],
    axis=0,
    ignore_index=True,
    sort=False,
)
combined = combined.sort_values(by=["user_id", "time"])
combined["count"] = combined.groupby("user_id")["is_log"].cumsum()
train = combined.loc[combined["is_log"] == 0]

print(log)
#        time1  user_id  is_log
# 0 2000-03-13        0       1
# 1 2000-06-08        0       1
# 2 2000-10-20        1       1
# 3 2000-08-04        1       1
# 4 2000-07-09        0       1

print(train)
屈服

         time  user_id  is_log  count
6  2000-01-17        0       0      0
7  2000-06-25        0       0      2
8  2000-07-18        0       0      3
10 2000-03-13        1       0      0
5  2000-04-16        1       0      0
9  2000-08-17        1       0      1
试试这个:试试这个: