Frage

Ich bin ein einfachen internen Rahmen der Gestaltung für Zeitreihendaten der Handhabung. Da LINQ ist mein aktuelles Spielzeug Hammer, ich will alles mit ihm treffen.

Ich mag Methoden in der Klasse Timeseries (Select (), Wo () und so weiter) implementieren, so dass ich LINQ-Syntax verwenden kann Zeitreihendaten

zu handhaben

Einige Sachen sind gerade nach vorne, z.B. (Von x in A select x + 10), eine neue Zeitreihe zu geben.

Was ist das beste Syntax Design für zwei oder mehr Zeitreihen zu kombinieren? (Von A in A von B in B wählen a + b) ist nicht groß, da er eine verschachtelte Schleife zum Ausdruck bringt. Vielleicht kommen einige? Dies sollte entspricht auf der impliziten Zeitvariable zu verbinden. (Was ich im Sinn haben, entspricht der Lisp ‚zip‘ -Funktion)


EDIT:. Einige Klarstellung ist notwendig,

Eine Zeitreihe ist eine Art von Funktion abhängig von der Zeit, z.B. Aktienkurse. Eine Kombination von Zeitreihe kann die Differenz zwischen zwei Aktienkursen, als Funktion der Zeit sein.

Stock1.MyJoin(Stock2, (a,b)=>a-b)

ist möglich, aber kann diese ordentlich Syntax einige LINQ ausgedrückt werden? Ich erwarte LINQ Methoden in class MyTimeSeries selbst zu implementieren.

War es hilfreich?

Lösung

Wenn ich die Frage richtig bin zu verstehen, wollen Sie sich auf ihre Position innerhalb der Sequenz mehrere Sequenzen basierend beitreten?

Es gibt nichts in der System.Linq.Enumerable Klasse sind sowohl diese als die Join und GroupJoin Methoden zu tun, basierend Tasten auf beizutreten. Doch durch Zufall ich diesen Zweck eine PositionalJoin Methode für nur schrieb ein paar Tage zurück, verwenden, wie in Ihrem Beispiel:

sequenceA.PositionalJoin(sequenceB, (a, b) => new { a, b });

Die Semantik des Verfahrens unten gezeigt ist, dass es nicht die Sequenzen erfordert gleich lang sein, aber es wäre trivial, ihn zu ändern, dies zu erfordern. Ich kommentierte auch, wo das Argument Prüfung sein sollte, wie es unsere internen Hilfsklassen wurde mit.

public static IEnumerable<TResult> PositionalJoin<T1, T2, TResult>(
    this IEnumerable<T1> source1, 
    IEnumerable<T2> source2, 
    Func<T1, T2, int, TResult> selector)
{
    // argument checking here
    return PositionalJoinIterator(source1, source2, selector);
}

private static IEnumerable<TResult> PositionalJoinIterator<T1, T2, TResult>(
    IEnumerable<T1> source1, 
    IEnumerable<T2> source2, 
    Func<T1, T2, TResult> selector)
{
    using (var enumerator1 = source1.GetEnumerator())
    using (var enumerator2 = source2.GetEnumerator())
    {
        bool gotItem;
        do
        {
            gotItem = false;

            T1 item1;
            if (enumerator1.MoveNext())
            {
                item1 = enumerator1.Current;
                gotItem = true;
            }
            else
            {
                item1 = default(T1);
            }

            T2 item2;
            if (enumerator2.MoveNext())
            {
                item2 = enumerator2.Current;
                gotItem = true;
            }
            else
            {
                item2 = default(T2);
            }

            if (gotItem)
            {
                yield return selector(item1, item2);
            }
        }
        while (gotItem);
    }
}

Nicht sicher, ob dies ist genau das, was Sie suchen, aber hoffentlich eine Hilfe.

Andere Tipps

Union klingt wie der richtige Weg zu gehen - ohne Abfrage Ausdruck Unterstützung, aber ich denke, es ausdrückt, was Sie meinen

.

Vielleicht haben Sie daran interessiert seinen Blick auf den bereichsbasierte Klassen in MiscUtil die schön für Zeiten verwendet werden. In Kombination mit ein bisschen Erweiterungsmethode Spaß, können Sie tun:

foreach (DateTime day in 19.June(1976).To(DateTime.Today).Step(1.Day()))
{
    Console.WriteLine("I'm alive!");
}

Ich schlage nicht vor dies sollte ersetzen, was auch immer Sie tun, nur, dass Sie ein paar Ideen zu übernehmen könnte der Lage sein, es sogar sauberere zu machen. Fühlen Sie sich frei zurück zu tragen, auch:)

Aus meiner NExtension Projekt:

public static IEnumerable<TResult> Zip<T1, T2, TResult>(
    this IEnumerable<T1> source1, 
    IEnumerable<T2> source2, 
    Func<T1, T2, TResult> combine)
{
    if (source1 == null)
        throw new ArgumentNullException("source1");
    if (source2 == null)
        throw new ArgumentNullException("source2");
    if (combine == null)
        throw new ArgumentNullException("combine");

    IEnumerator<T1> data1 = source1.GetEnumerator();
    IEnumerator<T2> data2 = source2.GetEnumerator();
    while (data1.MoveNext() && data2.MoveNext())
    {
        yield return combine(data1.Current, data2.Current);
    }
}

Die Syntax ist:

Stock1.Zip(Stock2, (a,b)=>a-b)

Bjarke, werfen Sie einen Blick auf Nesper, es ist ein Open-Source-Complex Event Processing-Anwendung, die unter anderem tut SQL-ähnliche Zeitreihen Abfragen. Sie können entweder lernen, wie sie es getan haben, oder vielleicht sogar ihren Code nutzen, um Ihr Ziel zu erreichen. hier Link http://esper.codehaus.org/about/nesper/nesper.html

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top