一种选择是进行'cross' 合并并使用索引过滤到基本上上三角形,这样您就不会重复计算 AB 和 BA 合并(第 1 行与第 2 行,第 2 行与第 1 行),并且还排除 AA 合并(第 1 行与自身合并)。
然后,结果会显示差异(以天为单位)以及用于形成差异的两个日期。如果您想记录这些日期的来源,可以删除代码中的 .drop(columns=['index_x', 'index_y']) 部分。
样本数据
import pandas as pd
df = pd.DataFrame({'date': ['2017-04-01 00:00:00', '2017-05-03 00:00:00',
'2017-10-17 00:00:00']})
df['date'] = pd.to_datetime(df.date)
代码
res = (pd.merge(df[['date']].reset_index(), df[['date']].reset_index(), how='cross')
.query('index_x > index_y')
.drop(columns=['index_x', 'index_y']))
res['diff'] = (res['date_y'] - res['date_x']).dt.days
print(res)
# date_x date_y diff
#3 2017-05-03 2017-04-01 -32
#6 2017-10-17 2017-04-01 -199
#7 2017-10-17 2017-05-03 -167
或者,您可以使用外部减法在 numpy 中执行此操作,然后提取值的下三角形(不包括对角线 k=1)。由于这些是以纳秒为单位计算的,因此我们需要将 10**9*60*60*24 转换为天数
import numpy as np
arr = df['date'].to_numpy()[:, None] - df['date'].to_numpy()[None, :]
days = arr[np.triu_indices(arr.shape[0], k=1)]/(10**9*60*60*24)
days
#array([ -32, -199, -167], dtype='timedelta64[ns]')