Pergunta

Eu estou projetando um quadro interno simples para manipulação de dados de séries temporais. Dado que LINQ é meu martelo brinquedo atual, eu quero bater tudo com ele.

Eu quero implementar métodos em TimeSeries classe (select (), onde () e assim por diante) para que eu possa usar sintaxe LINQ para dados de séries temporais alça

Algumas coisas são para a frente, por exemplo, (A partir de x em A escolha x + 10), dando uma nova série temporal.

O que é o melhor design de sintaxe para combinar duas ou mais séries de tempo? (A partir de um em à partir de b em B seleccionar a + b) não é grande, uma vez que expressa um loop aninhada. Talvez alguns se juntar? Este deve corresponder a juntar-se sobre a variável tempo implícito. (Função O que tenho em mente corresponde ao lisp 'zip')


EDIT:. Alguns esclarecimentos é necessário

Uma série temporal é um tipo de função, dependendo do tempo, por exemplo cotações de ações. Uma combinação de séries temporais pode ser a diferença entre dois preços das ações, como uma função do tempo.

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

É possível, mas isso pode ser expressa perfeitamente usando uma sintaxe LINQ? Estou esperando para implementar métodos LINQ em class MyTimeSeries mim mesmo.

Foi útil?

Solução

Se eu estou entendendo a pergunta corretamente, você quer se juntar várias seqüências com base em sua posição dentro da seqüência?

Não há qualquer coisa na classe System.Linq.Enumerable para fazer isso como métodos tanto o Join e GroupJoin são baseadas em se juntar chaves. No entanto, por coincidência eu escrevi um método PositionalJoin apenas para este fim de alguns dias atrás, usado como no seu exemplo:

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

A semântica do método mostrado abaixo é que ele não requer as sequências de ser de igual comprimento, mas seria trivial para modificá-lo para o exijam. Eu também comentada onde a verificação de argumento deve ser como ele estava usando nossas classes auxiliares internos.

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);
    }
}

Não sei se isso é exatamente o que você está procurando, mas espero que de alguma ajuda.

Outras dicas

sons Union como o caminho certo a seguir -. Nenhum apoio de expressão de consulta, mas eu acho que expressa o que você quer dizer

Você pode estar interessado em olhar para as classes baseadas-Range na MiscUtil que pode ser muito bem usado para vezes. Combinado com um pouco de diversão método de extensão, você pode fazer:

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

Eu não estou sugerindo isso deve substituir o que você está fazendo, só que você pode ser capaz de tomar algumas idéias para torná-lo ainda mais puro. Sinta-se livre para contribuir de volta, também:)

De minha NExtension projeto:

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);
    }
}

A sintaxe é:

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

Bjarke, dê uma olhada Nesper, é um complexo aplicativo de processamento de eventos de código aberto que, entre outras coisas faz SQL-como consultas de séries temporais. Você pode aprender como eles já fizeram isso, ou talvez até mesmo alavancar o seu código para atingir o seu objetivo. link aqui http://esper.codehaus.org/about/nesper/nesper.html

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top