Domanda

L'ultima domanda che ho posto riguardava il modo in cui binare i dati con x coordinate. La soluzione era semplice ed elegante, e mi vergogno di non averlo visto. Questa domanda potrebbe essere più difficile (o potrei essere solo cieco).

Ho iniziato con circa 140000 punti dati e li ho divisi in 70 gruppi equidistanti lungo l'asse x Ho quindi preso la posizione media (x_avg, y_avg) di ciascun gruppo e li ho tracciati; apparve una bella curva. Sfortunatamente ci sono due problemi. Innanzitutto, i bordi sono molto meno popolati rispetto al centro del grafico; In secondo luogo, alcune aree cambiano più di altre e quindi necessitano di una risoluzione migliore.

Ho quindi due domande specifiche e un invito generale a presentare suggerimenti:

Matlab ha un modo integrato di dividere una matrice in un numero fisso di matrici più piccole o matrici più piccole di dimensioni fisse?

Esiste un algoritmo (o una funzione matlab, ma lo trovo improbabile) per determinare i confini richiesti per raggruppare le aree di interesse in modo più fine?

Più in generale, esiste un modo migliore per condensare decine di migliaia di punti dati in una tendenza ordinata?

È stato utile?

Soluzione

Sembra che tu voglia usare contenitori di dimensioni variabili a seconda della densità dei valori x. Penso che puoi ancora usare la funzione HISTC come nella risposta al tuo post precedente, ma dovresti solo dargli un diverso set di bordi.

Non so se questo è esattamente quello che vuoi, ma ecco un suggerimento: invece di dividere l'asse x in 70 gruppi equidistanti, dividere i dati x ordinati in 70 gruppi uguali e determinare i valori dei bordi. Penso che questo codice dovrebbe funzionare:

% 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

Questo dovrebbe darti bidoni di dimensioni variabili con la densità dei dati.


AGGIORNAMENTO: un'altra versione ...

Ecco un'altra idea che mi è venuta dopo alcuni commenti. Con questo codice, si imposta una soglia (maxDelta) per la differenza tra punti dati vicini in x. Tutti i valori x che differiscono dal loro più grande vicino per un importo maggiore o uguale a maxDelta sono costretti a essere nel proprio cestino (tutti per il loro solitario). Scegli ancora un valore per nBins, ma il numero finale di bin sarà maggiore di questo valore quando i punti distribuiti vengono retrocessi nei propri bin.

% 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

L'ho provato su alcuni piccoli set di dati e sembra fare quello che dovrebbe. Speriamo che funzioni anche per il tuo set di dati, qualunque cosa contenga! =)

Altri suggerimenti

Non ho mai usato Matlab ma dall'esaminare la tua domanda precedente sospetto che tu stia cercando qualcosa sulla falsariga di un Kdtree o una variante.

Chiarimento: dato che sembra esserci un po 'di confusione su questo, penso che un esempio di pseudocodice sia in ordine.

// 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))
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top