Maison  >  Article  >  développement back-end  >  Comment normaliser les éléments d'un tableau dans une plage de temps ?

Comment normaliser les éléments d'un tableau dans une plage de temps ?

PHPz
PHPzavant
2024-02-08 21:30:35782parcourir

Comment normaliser les éléments dun tableau dans une plage de temps ?

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é.

Contenu de la question

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 ?

Éditeur :

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:0000: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

La solution de contournement

est en n 点之间有 n-1 段。这意味着,如果您想在插值中包含 startend,则时间段数(即 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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer