php-Editor Xinyi stellt Ihnen vor, wie Sie die Elemente eines Arrays innerhalb eines Zeitbereichs standardisieren. In der Entwicklung müssen wir häufig Zeitreihendaten verarbeiten, und diese Daten können Zeitsprünge oder fehlende Situationen aufweisen. Um die Genauigkeit und Vollständigkeit der Daten sicherzustellen, müssen wir die Elemente im Array standardisieren. Durch die Normalisierung werden die Elemente eines Arrays in chronologische Reihenfolge gebracht und fehlende Zeitpunkte ergänzt. Im Folgenden wird detailliert beschrieben, wie diese Funktion implementiert wird.
Ich versuche, eine Reihe von Elementen über einen bestimmten Zeitraum zu normalisieren. Nehmen wir an, Sie haben 20 Banktransaktionen, die am 1. Januar 2022 stattgefunden haben
transaction 1 - 2022/01/01 transaction 2 - 2022/01/01 ... transaction 20 - 2022/01/01
Wir haben keine anderen Daten als das Datum, an dem sie auftreten, aber wir möchten ihnen dennoch eine Stunde des Tages zuordnen, sodass sie am Ende wie folgt lauten:
transaction 1 - 2022/01/01 00:00 transaction 2 - 2022/01/01 ??:?? ... transaction 20 - 2022/01/01 23:59
In go habe ich eine Funktion, die versucht, die Normalisierung einer Tageszeit für einen Index in einem Array von Elementen zu berechnen:
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) }
Allerdings habe ich versehentlich 1.1.2022 05:59 bei Index 0 im 4-Elemente-Array im Zeitbereich von 1.1.2022 00:00 bis 1.1.2022 23:59 berechnet, stattdessen habe ich es erwartet Siehe 01.01.2022 00:00. Der einzige, der unter diesen Bedingungen korrekt funktioniert, ist Index 3.
Was mache ich also falsch mit der Normalisierung?
Dies ist die von @icza behobene Funktion
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) }
Hier ist ein Beispiel: Nehmen wir an, unser Start- und Enddatum ist 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)
Da zwischen Startzeit und Endzeit nur 4 Minuten normalisierter Zeit (von 00:00
到 00:03
),并且想要查找数组(大小 3
)中最后一个条目(索引 2
) liegen, sollte das Ergebnis wie folgt lauten:
fmt.Printf("%t", result.Equal(time.Date(2022, time.January, 1, 0, 3, 0, 0, time.UTC)) // prints "true"
oder die letzte Minute im Bereich, die 00:03
ist.
Hier ist ein reproduzierbares Beispiel: https://go.dev/play/p/ezwkqanv1at
ist in n
点之间有 n-1
段。这意味着,如果您想在插值中包含 start
和 end
,则时间段数(即 delta
)为 arraysize - 1
.
Auch, wenn so 1
添加到 index
,则结果不可能是 start
(您将跳过 00:00
).
Der richtige Algorithmus ist also dieser:
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) }
Probieren Sie es auf dem Go-Spielplatz aus.
Beachten Sie außerdem, dass Sie bei vielen Transaktionen (geordnet nach Tagesminuten, etwa tausend) leicht mehrere Transaktionen mit demselben Zeitstempel (gleiche Stunde und Minute) erhalten können. Wenn Sie dies vermeiden möchten, verwenden Sie eine kleinere Genauigkeit als Minuten, beispielsweise Sekunden oder Millisekunden:
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) }
Ja, dies führt zu Zeitstempeln mit Sekunden, die auch nicht unbedingt Null sind, stellt aber sicher, dass höhere Transaktionsvolumina unterschiedliche, eindeutige Zeitstempel haben.
Wenn Ihre Transaktionen in der Größenordnung von Sekunden pro Tag liegen (d. h. 86400), können Sie diese „Einheit“ vollständig entfernen und time.duration
selbst (d. h. Nanosekunden) verwenden. Dies garantiert die Eindeutigkeit des Zeitstempels selbst für die größte Anzahl von Transaktionen:
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)) }
Um dies mit 1 Million Transaktionen zu testen, sind hier die ersten 15 Zeitteile (sie werden nur im Teilsekundenteil verzögert):
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
Versuchen Sie es auf dem Go-Spielplatz.
Das obige ist der detaillierte Inhalt vonWie normalisiert man die Elemente eines Arrays innerhalb eines Zeitbereichs?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!