Python 01/2016,02:03:00,7261824,871631182 01/01/2016,06:05:00,7261824,871631183 01/01/2016,11:04:00,7261824,871631184 01/01/2016,14:10:00,7261824,871631185 ''),解析日期=dtc) df1['date\u start\u time']=pd.to\u datetime(df1['date\u start\u time']) df2['date\u start\u time']=pd.to\u datetime(df2['date\u start\u time']) #将其转换为索引,这样我们可以保留日期\开始\时间列,这样您就可以验证合并逻辑 df1.index=df1['date\u start\u time'] df2.index=df2['date\u start\u time'] #魔术发生在下面,检查方向和公差参数 tol=pd.Timedelta(5分钟) pd.merge_asof(左=df1,右=df2,右=真,左=真,方向=最近,公差=tol)

Python 01/2016,02:03:00,7261824,871631182 01/01/2016,06:05:00,7261824,871631183 01/01/2016,11:04:00,7261824,871631184 01/01/2016,14:10:00,7261824,871631185 ''),解析日期=dtc) df1['date\u start\u time']=pd.to\u datetime(df1['date\u start\u time']) df2['date\u start\u time']=pd.to\u datetime(df2['date\u start\u time']) #将其转换为索引,这样我们可以保留日期\开始\时间列,这样您就可以验证合并逻辑 df1.index=df1['date\u start\u time'] df2.index=df2['date\u start\u time'] #魔术发生在下面,检查方向和公差参数 tol=pd.Timedelta(5分钟) pd.merge_asof(左=df1,右=df2,右=真,左=真,方向=最近,公差=tol),python,pandas,Python,Pandas,我建议使用内置的pandas Series dt round函数,将两个数据帧取整到一个公共时间,例如每5分钟取整一次。因此,时间将始终采用以下格式:例如,01:00:00,然后是01:05:00。这样,两个数据帧将有相似的时间索引来执行合并 请参阅此处的文档和示例我建议使用内置的pandas Series dt round函数,将两个数据帧舍入到一个公共时间,例如每5分钟舍入一次。因此,时间将始终采用以下格式:例如,01:00:00,然后是01:05:00。这样,两个数据帧将有相似的时间索引来

我建议使用内置的pandas Series dt round函数,将两个数据帧取整到一个公共时间,例如每5分钟取整一次。因此,时间将始终采用以下格式:例如,01:00:00,然后是01:05:00。这样,两个数据帧将有相似的时间索引来执行合并


请参阅此处的文档和示例

我建议使用内置的pandas Series dt round函数,将两个数据帧舍入到一个公共时间,例如每5分钟舍入一次。因此,时间将始终采用以下格式:例如,01:00:00,然后是01:05:00。这样,两个数据帧将有相似的时间索引来执行合并



请参见此处的文档和示例

有趣的问题。最简单的解决方案是将时间戳四舍五入到最接近的5分钟进行合并,但如果某些会话恰好位于5分钟标记的不同侧面,则会将它们保留为单独的行。您可以使用随机偏移量迭代应用该过程,最多迭代一定次数,这将产生更好的结果。最稳健的解决方案是聚类算法,但这更难实现。可以提供一些启发。理想情况下,您希望在
join
操作上使用SQL风格的
where
子句,该子句使用
介于
和基于另一个日期的两个界限之间的日期来指定其中一个日期。如果直接在数据库中这样做是可行的,或者使用像SQLite这样的内存数据库,我建议使用它。您需要在pandas中进行的黑客攻击将是不好的,如果您使用数据库方式进行攻击,您仍然可以在之后将结果拉出来给pandas进行交互处理或其他任何操作。@Lance是否可以保证两个数据帧分别包含真正唯一的会话?i、 e.重复数据消除是否仅在合并它们时适用?或者同一数据帧中的“同一”会话是否可能有两行时间戳略有不同?对不起,我还是不明白。在单个数据帧内,是否需要执行会话重复数据消除(考虑时间戳的微小差异)?一个有趣的问题。最简单的解决方案是将时间戳四舍五入到最接近的5分钟进行合并,但如果某些会话恰好位于5分钟标记的不同侧面,则会将它们保留为单独的行。您可以使用随机偏移量迭代应用该过程,最多迭代一定次数,这将产生更好的结果。最稳健的解决方案是聚类算法,但这更难实现。可以提供一些启发。理想情况下,您希望在
join
操作上使用SQL风格的
where
子句,该子句使用
介于
和基于另一个日期的两个界限之间的日期来指定其中一个日期。如果直接在数据库中这样做是可行的,或者使用像SQLite这样的内存数据库,我建议使用它。您需要在pandas中进行的黑客攻击将是不好的,如果您使用数据库方式进行攻击,您仍然可以在之后将结果拉出来给pandas进行交互处理或其他任何操作。@Lance是否可以保证两个数据帧分别包含真正唯一的会话?i、 e.重复数据消除是否仅在合并它们时适用?或者同一数据帧中的“同一”会话是否可能有两行时间戳略有不同?对不起,我还是不明白。在单个数据帧内,您是否需要执行会话重复数据消除(考虑时间戳的微小差异)?对于我来说,这是一个很好的开始。关于您的第一个解决方案,我们是否可以包括一个正负间隔范围,以防止事件位于间隔的错误一侧?间隔将是一个字符串,如我键入的示例中所示。不确定逻辑是否100%正确,但我让它在excel中处理测试数据。我想你的也会遇到同样的问题。考虑到将一个连续的时间范围映射成离散的区间。这意味着您总是可以想到一对时间戳,它们在连续范围内足够接近,但属于不同的间隔。我不确定我的方法是否完全等同于你的方法(虽然我认为可能是),但总的想法是正确的。哈哈,真让人头疼。谢谢,不过我稍后会测试,并会让你知道。它至少可以提高我的匹配性,因为我刚刚意识到,使用间隔装箱解决方案可以使它变得更好。直到现在才知道这个方法。这看起来很有趣,但文档完全没有帮助。我以前没有使用过DateTimeIndex,所以我不太确定如何继续。df1=df1.set_index(pd.DatetimeIndex(df1['call_start',,drop=False)),它似乎已经创建了索引,但我尝试了几次添加.snap的尝试,但没有成功。当我在谷歌上搜索时,我在网上找不到一个很好的例子,这对我来说是一个很好的开始。关于您的第一个解决方案,我们是否可以包括一个正负间隔范围,以防止事件位于间隔的错误一侧?间隔将是一个字符串,如我键入的示例中所示。不确定逻辑是否100%正确,但我让它在excel中处理测试数据。我想你的
date    start_time  employee_id session_id
01/01/2016  01/01/2016 06:03:13 7261824 871631182
date    start_time  employee_id session_id
01/01/2016  01/01/2016 06:03:37 7261824 871631182
['employee_id', 'session_id', 'timestamp<5minutes']
df1['low_time'] = df1['start_time'] - timedelta(minutes=5)
df1['high_time'] = df1['start_time'] + timedelta(minutes=5)
df1['interval_string'] = df1['low_time'].astype(str) + df1['high_time'].astype(str)
pd.merge(df1, df2, how = 'left', on = ['employee_id', 'session_id', 'date', 'interval_string']
from io import StringIO
from pandas import read_csv, to_datetime

# how close do sessions have to be to be considered equal? (in minutes)
threshold = 5

# datetime column (combination of date + start_time)
dtc = [['date', 'start_time']]

# index column (above combination)
ixc = 'date_start_time'

df1 = read_csv(StringIO(u'''
date,start_time,employee_id,session_id
01/01/2016,02:03:00,7261824,871631182
01/01/2016,06:03:00,7261824,871631183
01/01/2016,11:01:00,7261824,871631184
01/01/2016,14:01:00,7261824,871631185
'''), parse_dates=dtc)

df2 = read_csv(StringIO(u'''
date,start_time,employee_id,session_id
01/01/2016,02:03:00,7261824,871631182
01/01/2016,06:05:00,7261824,871631183
01/01/2016,11:04:00,7261824,871631184
01/01/2016,14:10:00,7261824,871631185
'''), parse_dates=dtc)
>>> df1
      date_start_time  employee_id  session_id
0 2016-01-01 02:03:00      7261824   871631182
1 2016-01-01 06:03:00      7261824   871631183
2 2016-01-01 11:01:00      7261824   871631184
3 2016-01-01 14:01:00      7261824   871631185
>>> df2
      date_start_time  employee_id  session_id
0 2016-01-01 02:03:00      7261824   871631182
1 2016-01-01 06:05:00      7261824   871631183
2 2016-01-01 11:04:00      7261824   871631184
3 2016-01-01 14:10:00      7261824   871631185
import numpy as np

# half-threshold in nanoseconds
threshold_ns = threshold * 60 * 1e9

# compute "interval" to which each session belongs
df1['interval'] = to_datetime(np.round(df1.date_start_time.astype(np.int64) / threshold_ns) * threshold_ns)
df2['interval'] = to_datetime(np.round(df2.date_start_time.astype(np.int64) / threshold_ns) * threshold_ns)

# join
cols = ['interval', 'employee_id', 'session_id']
print df1.merge(df2, on=cols, how='outer')[cols]
             interval  employee_id  session_id
0 2016-01-01 02:05:00      7261824   871631182
1 2016-01-01 06:05:00      7261824   871631183
2 2016-01-01 11:00:00      7261824   871631184
3 2016-01-01 14:00:00      7261824   871631185
4 2016-01-01 11:05:00      7261824   871631184
5 2016-01-01 14:10:00      7261824   871631185
from datetime import timedelta

# get closest match from "df2" to row from "df1" (as long as it's below the threshold)
def closest(row):
    matches = df2.loc[(df2.employee_id == row.employee_id) &
                      (df2.session_id == row.session_id)]

    deltas = matches.date_start_time - row.date_start_time
    deltas = deltas.loc[deltas <= timedelta(minutes=threshold)]

    try:
        return matches.loc[deltas.idxmin()]
    except ValueError:  # no items
        return row

# replace timestamps in "df1" with closest timestamps in "df2"
df1 = df1.apply(closest, axis=1)

# join
cols = ['date_start_time', 'employee_id', 'session_id']
print df1.merge(df2, on=cols, how='outer')[cols]
      date_start_time  employee_id  session_id
0 2016-01-01 02:03:00      7261824   871631182
1 2016-01-01 06:05:00      7261824   871631183
2 2016-01-01 11:04:00      7261824   871631184
3 2016-01-01 14:01:00      7261824   871631185
4 2016-01-01 14:10:00      7261824   871631185
date_start_time date_start_time_x   employee_id_x   session_id_x    date_start_time_y   employee_id_y   session_id_y

2016-01-01 02:03:00 2016-01-01 02:03:00 7261824 871631182   2016-01-01 02:03:00 7261824.0   871631182.0
2016-01-01 06:03:00 2016-01-01 06:03:00 7261824 871631183   2016-01-01 06:05:00 7261824.0   871631183.0
2016-01-01 11:01:00 2016-01-01 11:01:00 7261824 871631184   2016-01-01 11:04:00 7261824.0   871631184.0
2016-01-01 14:01:00 2016-01-01 14:01:00 7261824 871631185   NaT NaN NaN