Pergunta

A última pergunta que fiz em causa como dados bin pela coordenada x. A solução foi simples e elegante, e eu tenho vergonha eu não vê-lo. Esta questão pode ser mais difícil (ou I pode apenas ser cego).

I começou com cerca de 140.000 pontos de dados e dividi-las em grupos de 70, igualmente espaçadas ao longo do eixo x Tomei, então, a posição média (x_avg, y_avg) de cada grupo e representada graficamente-los; uma curva agradável apareceu. Infelizmente, existem dois problemas. Em primeiro lugar, as bordas são muito menos povoadas do que o centro do gráfico; Em segundo lugar, algumas áreas mudar mais do que outros e, portanto, precisamos de uma melhor resolução.

Eu, portanto, tenho duas perguntas específicas e um convite geral para lançar sugestões:

O MATLAB tem uma maneira builtin de dividir uma matriz em qualquer um número fixo de matricies menores ou matricies menores de um tamanho fixo?

Existe um algoritmo (ou uma função Matlab, mas eu acho que improvável) para determinar os limites necessários para regiões bin de interesse mais finamente?

De modo mais geral, há uma maneira melhor de condensação dezenas de milhares de pontos de dados em uma tendência arrumado?

Foi útil?

Solução

Parece que você deseja utilizar caixas que variam em tamanho dependendo da densidade de valores x. Eu acho que você ainda pode usar a função HISTC como na resposta ao seu post anterior, mas você só tem que dar-lhe um conjunto diferente de bordas.

Eu não sei se isso é exatamente o que quer, mas aqui está uma sugestão: em vez de divisão do eixo x em 70 grupos igualmente espaçados, dividir os dados x classificados em 70 grupos iguais e determinar os valores de ponta. Eu acho que este código deve funcionar:

% Start by assuming x and y are vectors of data:

nBins = 70;
nValues = length(x);
[xsort,index] = sort(x);  % Sort x in ascending order
ysort = y(index);         % Sort y the same way as x
binEdges = [xsort(1:ceil(nValues/nBins):nValues) xsort(nValues)+1];

% Bin the data and get the averages as in previous post (using ysort instead of y):

[h,whichBin] = histc(xsort,binEdges);

for i = 1:nBins
    flagBinMembers = (whichBin == i);
    binMembers = ysort(flagBinMembers);
    binMean(i) = mean(binMembers);
end

Este deve dar-lhe caixas que variam em tamanho, com a densidade de dados.


UPDATE: Outra versão ...

Aqui está uma outra idéia que surgiu com depois de alguns comentários. Com esse código, você define um limite (Maxdelta) para a diferença entre vizinhos pontos de dados em x. Qualquer X valores que diferem do seu vizinho maior por uma quantidade maior do que ou igual a Maxdelta são forçados a estar na sua própria bin (todos por sua solitário). Você ainda escolher um valor para nBins, mas o número final de caixas será maior do que este valor quando os pontos de spread-out são relegados para as suas próprias caixas.

% Start by assuming x and y are vectors of data:

maxDelta = 10; % Or whatever suits your data set!
nBins = 70;
nValues = length(x);
[xsort,index] = sort(x);  % Sort x in ascending order
ysort = y(index);         % Sort y the same way as x

% Create bin edges:

edgeIndex = false(1,nValues);
edgeIndex(1:ceil(nValues/nBins):nValues) = true;
edgeIndex = edgeIndex | ([0 diff(xsort)] >= maxDelta);
nBins = sum(edgeIndex);
binEdges = [xsort(edgeIndex) xsort(nValues)+1];

% Bin the data and get the y averages:

[h,whichBin] = histc(xsort,binEdges);

for i = 1:nBins
    flagBinMembers = (whichBin == i);
    binMembers = ysort(flagBinMembers);
    binMean(i) = mean(binMembers);
end

Eu testei isso em alguns pequenos conjuntos de amostras de dados e parece fazer o que é suposto. Esperemos que ele vai trabalhar para o seu conjunto de dados também, tudo o que ele contém! =)

Outras dicas

Eu nunca usei Matlab, mas de olhar para a sua pergunta anterior eu suspeito que você está procurando algo ao longo das linhas de um Kdtree ou uma variação.

Esclarecimento:. Desde parece haver alguma confusão sobre isso eu acho que um exemplo pseudocódigo está em ordem

// Some of this shamelessly borrowed from the wikipedia article
function kdtree(points, lower_bound, upper_bound) {
    // lower_bound and upper_bound are the boundaries of your bucket
    if(points is empty) {
        return nil
    }
    // It's a trivial exercise to control the minimum size of a partition as well
    else {
        // Sort the points list and choose the median element
        select median from points.x

        node.location = median;

        node.left = kdtree(select from points where lower_bound < points.x <= median, lower_bound, median);
        node.right = kdtree(select from points where median < points.x <= upper_bound, median, upper_bound);

        return node
    }
}

kdtree(points, -inf, inf)

// or alternatively

kdtree(points, min(points.x), max(points.x))
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top