Comment générer dynamiquement des bandes / groupes de données avec des nombres similaires dans chacun?

StackOverflow https://stackoverflow.com/questions/4520230

  •  12-10-2019
  •  | 
  •  

Question

Je veux générer dynamiquement des bandes, qui seront ensuite regroupées dans des rapports.

Ma première pensée a été de générer les bandes en prenant la valeur minimale et la valeur maximale, puis en divisant la différence.

Par exemple, supposons que vous ayez les salaires pour un grand groupe de personnes:

  • Le moins bas gagne 12 000 £ par an et le plus élevé gagne 3 000 000 £
  • J'ai donc divisé cela en 10 bandes de taille similaire: (3 millions de livres sterling - 12 000 £) / 10 = 298800 £
  • Donc, mon premier groupe va de 12 000 £ à 310 800 £ et obtient des milliers de personnes dedans
  • Mon deuxième groupe va de 310 000 £ à 610 000 £ et a quelques centaines
  • Chaque autre groupe a quelques personnes dans chacun

Donc, ce n'est pas vraiment très utile. Si je devais créer manuellement les groupes, je voudrais des chiffres à peu près similaires dans chacun, quelque chose comme: 12 000 £ à 14 000 £, 14 000 £ à 18 000 £, £ 18k - 25 000 £, 25 £ à 35 000 £, ..., £ 1,5 - 3 millions de livres sterling

Ce n'est qu'un exemple - il pourrait y avoir beaucoup de distributions différentes.

Je recherche un algorithme pour générer les bandes, afin que les utilisateurs saisissent le nombre de bandes qu'ils souhaitent et les données seraient regroupées dans autant de bandes avec un numéro similaire dans chacun.

Le groupe doit être rapide - je ne peux pas simplement parcourir l'ensemble de données.

L'application est C # en plus de SQL, mais les solutions des autres langues sont les bienvenues.

Était-ce utile?

La solution

Je pense que vous demandez comment interroger un ensemble de données existant dans les «groupes» ...

Si cela est vrai, alors Oracle prend en charge les fonctions d'agrégats ntile à cet effet. Il devrait y avoir des équivalents dans d'autres implémentations SQL.

Autres conseils

Avez-vous regardé Ntile? SQL Server et la plupart des SGBD le prennent en charge.

Par exemple:

select b.band, count(*), min(b.valuefield), max(b.valuefield)
from ( 
    select ntile(10) over (order by valuefield) as 'band', valuefield
    from table ) b
group by b.band

Vous regardez le problème du mauvais point de vue. Au lieu de regarder le salaire, regardez la position ordonnée de la personne dans la gamme de salaires triée. Mettez l'algorithme de côté pendant une seconde et pensez-y mathématiquement.

Prenez tout votre peuple et triez-les par salaire. Désormais séquentiellement les numéroter de 1 jusqu'à N, le dernier avec le salaire le plus élevé. Si vous avez besoin de groupes M, chaque groupe contient des personnes N / M. Ainsi, la première bande salariale passe de 0 à la personne [n / m]. Salaire, la seconde passe de là à la personne [2 * n / m]. Salaire et ainsi de suite.

En C #, vous pouvez le faire assez efficacement dans Linq. Quelque chose comme ça. C'est du code non testé, c'est un concept et non une solution finale, il y a probablement des problèmes de condition de bord auquel je n'ai pas pensé.

List<int> GetBands(int numBands)
{
    using(var db = new MyContext())    
    {
        var list SalaryBands = new List<int>();
        var count = db.People.Count();
        var salaries = db.People.OrderBy(item => item.Salary)
                                .Select(item => item.Salary);
        int skipCount = count / numBands;
        for(int segmentNum = 0; segmentNum < numBands; segmentCount++)
        {
            salaries = salaries.Skip(skipCount);
            salaryBands.Add(salaries.First());
        }
        return salaryBands;
    }
}

Première observation, vous voulez un graphique de type log, par opposition à la linéaire droite.

Deuxième observation: je construis généralement de grands ensembles de données d'échantillons (semblables à votre exemple donné), puis je cherche mes facteurs communs et je dérive un système de formule des données réelles. Pouvez-vous poster d'autres scénarios?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top