l'éditeur php Xinyi vous présente comment standardiser les éléments d'un tableau dans une plage de temps. En développement, nous devons souvent traiter des données de séries chronologiques, et ces données peuvent présenter des sauts dans le temps ou des situations manquantes. Afin de garantir l'exactitude et l'exhaustivité des données, nous devons standardiser les éléments du tableau. La normalisation place les éléments d'un tableau dans l'ordre chronologique et remplit les points temporels manquants. Ci-dessous, nous détaillerons comment implémenter cette fonctionnalité.
J'essaie de normaliser un tableau d'éléments sur une plage de temps. Disons que vous avez 20 transactions bancaires effectuées le 1er janvier 2022
transaction 1 - 2022/01/01 transaction 2 - 2022/01/01 ... transaction 20 - 2022/01/01
Nous n'avons pas d'autres données que la date à laquelle ils se produisent, mais nous souhaitons quand même leur attribuer une heure de la journée, donc ils finissent par être :
transaction 1 - 2022/01/01 00:00 transaction 2 - 2022/01/01 ??:?? ... transaction 20 - 2022/01/01 23:59
En go j'ai une fonction qui tente de calculer la normalisation d'une heure de la journée pour un index dans un tableau d'éléments :
func normal(start, end time.time, arraysize, index float64) time.time { delta := end.sub(start) minutes := delta.minutes() duration := minutes * ((index+1) / arraysize) return start.add(time.duration(duration) * time.minute) }
Cependant, j'ai accidentellement calculé le 1/1/2022 05:59 à l'index 0 dans le tableau à 4 éléments dans la plage horaire du 1/1/2022 00:00 au 1/1/2022 23:59, à la place, je m'attendais Voir 1/1/2022 00:00. Le seul qui fonctionne correctement dans ces conditions est l’index 3.
Alors, qu'est-ce que je fais de mal avec la normalisation ?
C'est la fonction corrigée par @icza
func timeindex(min, max time.time, entries, position float64) time.time { delta := max.sub(min) minutes := delta.minutes() if position < 0 { position = 0 } duration := (minutes * (position / (entries - 1))) return min.add(time.duration(duration) * time.minute) }
Voici un exemple : disons que nos dates de début et de fin sont 2022/01/01 00:00
- 2022/01/01 00:03
,我们的银行交易数组中有 3 个条目,我们希望获取第 3 号交易的标准化时间(数组中的 2
) :
result := timeindex(time.date(2022, time.january, 1, 0, 0, 0, 0, time.utc), time.date(2022, time.january, 1, 0, 3, 0, 0, time.utc), 3, 2)
Comme il n'y a que 4 minutes de temps normalisé (à partir de 00:00
到 00:03
),并且想要查找数组(大小 3
)中最后一个条目(索引 2
) entre l'heure de début et l'heure de fin, le résultat devrait être :
fmt.Printf("%t", result.Equal(time.Date(2022, time.January, 1, 0, 3, 0, 0, time.UTC)) // prints "true"
ou la dernière minute de la gamme, soit 00:03
.
Voici un exemple reproductible : https://go.dev/play/p/ezwkqanv1at
est en n
点之间有 n-1
段。这意味着,如果您想在插值中包含 start
和 end
,则时间段数(即 delta
)为 arraysize - 1
.
Aussi, si c'est le cas 1
添加到 index
,则结果不可能是 start
(您将跳过 00:00
).
Donc, l'algorithme correct est le suivant :
func normal(start, end time.time, arraysize, index float64) time.time { minutes := end.sub(start).minutes() duration := minutes * (index / (arraysize - 1)) return start.add(time.duration(duration) * time.minute) }
Essayez-le sur le go terrain de jeu.
Notez également que si vous avez beaucoup de transactions (classées par minute de la journée, environ un millier), vous pouvez facilement vous retrouver avec plusieurs transactions avec le même horodatage (même heure et même minute). Si vous voulez éviter cela, utilisez une précision inférieure aux minutes, comme les secondes ou les millisecondes :
func normal(start, end time.time, arraysize, index float64) time.time { sec := end.sub(start).seconds() duration := sec * (index / (arraysize - 1)) return start.add(time.duration(duration) * time.second) }
Oui, cela entraînera des secondes d'horodatage qui ne seront pas nécessairement nulles non plus, mais garantira que les volumes de transactions plus élevés auront des horodatages différents et uniques.
Si vos transactions sont de l'ordre de quelques secondes par jour (c'est-à-dire 86400), alors vous pouvez supprimer entièrement cette "unité" et utiliser time.duration
elle-même (c'est-à-dire des nanosecondes). Cela garantira l'unicité de l'horodatage même pour le plus grand nombre de transactions :
func normal(start, end time.time, arraysize, index float64) time.time { delta := float64(end.sub(start)) duration := delta * (index / (arraysize - 1)) return start.add(time.duration(duration)) }
En testant cela avec 1 million de transactions, voici les 15 premières parties temporelles (elles ne sont retardées que dans la sous-seconde partie) :
0 - 00:00:00.00000 1 - 00:00:00.08634 2 - 00:00:00.17268 3 - 00:00:00.25902 4 - 00:00:00.34536 5 - 00:00:00.43170 6 - 00:00:00.51804 7 - 00:00:00.60438 8 - 00:00:00.69072 9 - 00:00:00.77706 10 - 00:00:00.86340 11 - 00:00:00.94974 12 - 00:00:01.03608 13 - 00:00:01.12242 14 - 00:00:01.20876 15 - 00:00:01.29510 16 - 00:00:01.38144 17 - 00:00:01.46778 18 - 00:00:01.55412 19 - 00:00:01.64046
Essayez ceci sur le go terrain de jeu.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!