我想根据它们的时间信息计算项目(0,1,2,3..)之间的相似性。时间信息可以是时间瞬间(开始日期)、时间间隔(开始日期、结束日期)或空值(NaT);请参阅下面的数据框(df_for)示例。
- {instant,instant} :如果等于 sim = 1,否则 sim =0
- {instant,null} 或反之,sim =0
- {instant, interval}:如果区间内的瞬间,sim =1 或者如果一个区间包含一个瞬间,sim = 1
- {interval,interval} :如果区间重叠,sim = 两个区间的交集/两个区间的并集
- {interval,interval} :如果一个区间包含另一个,则 sim = 1
以下 python 代码从数据帧中获取时间信息并执行上述条件 (1-5)。代码很冗长,我想知道是否有一种聪明的方式/lib来使用python计算时间段和时间瞬间之间的相似性。
m, k = df_for.shape
sim = np.zeros((m, m))
data = df_for.values
for i in range(m):
for j in range(m):
if i != j:
st1 = data[i][0]
ed1 = data[i][1]
st2 = data[j][0]
ed2 = data[j][1]
#both items are null values
if pd.isnull(st1) and pd.isnull(ed1) and pd.isnull(st2) and pd.isnull(ed2):
sim[i][j] = 0.
# {instant, instant} => equal, not equal
if pd.notnull(st1) and pd.isnull(ed1) and pd.notnull(st2) and pd.isnull(ed2):
if st1 == st2:
sim[i][j] = 1.
else:
sim[i][j] = 0.
# {instant, null} => sim is 0
if pd.notnull(st1) and pd.isnull(ed1) and pd.isnull(st2) and pd.isnull(ed2):
sim[i][j] = 0.
# {instant, interval} => meets, during
if pd.notnull(st1) and pd.isnull(ed1) and pd.notnull(st2) and pd.notnull(ed2):
if(st2 <= st1 <= ed2):
sim[i][j] = 1. #a time is between two other times
else:
sim[i][j] = 0.
# {interval, instant} => meets, contains
if pd.notnull(st1) and pd.notnull(ed1) and pd.notnull(st2) and pd.isnull(ed2):
if(st1 <= st2 <= ed1):
sim[i][j] = 1. #a time is between two other times
else:
sim[i][j] = 0.
# {interval, interval} => equal, overlaps, not overlaps
if pd.notnull(st1) and pd.notnull(ed1) and pd.notnull(st2) and pd.notnull(ed2):
if (st1 <= st2 <= ed1) or (st2 <= st1 <= ed2):
intersect = min(ed1,ed2)- max(st1,st2) # earliestend-lateststart
union = max(st1,st2,ed1,ed2) - min(ed1,ed2,st1,st2)
overlaps = intersect/union
#print(intersect/np.timedelta64(1, 'D'),union/np.timedelta64(1, 'D'))
if (st1 > st2 and ed1 < ed2) or (st1 < st2 and ed1 > ed2): # contains, during
overlaps = 1.0
sim[i][j]=overlaps
else:
sim[i][j] = 0.
else:
sim[i][j] = 1.