Je souhaite calculer la similarité entre les éléments (0,1,2,3 ..) en fonction de leurs informations temporelles. L'information temporelle peut être un instant (startdate), un intervalle de temps (startdate, enddate) ou null (NaT); voir un exemple de données (df_for) ci-dessous.Python - Calcul des similitudes entre les éléments en fonction des informations temporelles (instantané, intervalle)
- {instant, instant}: si sim égale = 1, autre sim = 0
- {instant, null} ou vice versa, sim = 0
- {instant, intervalle} : si instant dans intervalle, sim = 1 ou si un intervalle contient un instant, sim = 1
- {intervalle, intervalle}: si les intervalles se chevauchent, sim = intersection des deux intervalles/union des deux intervalles
- {intervalle, intervalle}: si un dans terval en contient un autre, puis sim = 1
Le code python suivant obtient des informations temporelles à partir de la trame de données et remplit les conditions ci-dessus (1-5). Le code est verbeux, je me demande s'il existe une méthode intelligente/lib pour calculer la similarité entre les périodes et les instants en utilisant 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.
Merci d'avoir amélioré le code. est le min_interval se référant à «la taille de l'intervalle plus petit (plutôt que la taille de l'union)»? J'ai mis à jour ed1, ed2 dans votre code à et1, et2 .. – kitchenprinzessin
Ouais, c'est ce que cette partie du code est destiné à faire. J'ai manqué quelques variables 'ed', donc j'ai modifié pour les corriger. – Blckknght
merci.Je me demande si ce cas (discontinuité dans la similarité) pourrait s'appliquer à {instant, instant} aussi. – kitchenprinzessin