Среднее значение C # среди расчета группы - PullRequest
0 голосов
/ 04 марта 2019

Мне нужно вычислить медиану для группы значений в одной из моих функций C #.Я использовал формулу с сайта, mathisfun .Ниже приведены моя модель данных и код.

public class DataModel
{
    public string Group { get; set; }

    public long? Population { get; set; }
}

Пример списка данных выглядит следующим образом:

> dataList Count = 7
>     [0]: {DataModel}
>       Group: "16 to 24"       Population: 39657245
>     [1]: {DataModel}      Group: "25 to 34"       Population: 58957845
>     [2]: {DataModel}      Group: "35 to 44"       Population: 12557845
>     [3]: {DataModel}      Group: "45 to 54"       Population: 25698746
>     [4]: {DataModel}      Group: "55 to 64"       Population: 325487

Ниже приведена логика функции, которая принимает dataList в качестве входного значения и возвращает медианное значение.как вывод.

public int CalculateMedianAge(IList<DataModel> dataList)
        {
            int median = 0;
            var sum = 0;
            var sumRange = 0;
            DataModel medianGroup = new DataModel();

            foreach (var item in dataList)
            {               
                    sum = sum + (int)item.Population;               
            }
            int range = (sum + 1) / 2;          
            foreach(var entry in dataList)
            {
                sumRange = sumRange + (int)entry.Population;
                if (range > sumRange)
                    continue;
                else
                {
                    medianGroup = entry;
                    break;
                }
            }
            var lowerBoundary = int.Parse(medianGroup.Group.Split(' ')[0]) - 0.5;
            var cumulativeFrequency = 0;
            for (int s = 0; s< dataList.IndexOf(medianGroup); s++)
            {
                cumulativeFrequency = cumulativeFrequency + (int)dataList[s].Population;
            }           
            var width = int.Parse(medianGroup.Group.Split(' ')[2]) - int.Parse(medianGroup.Group.Split(' ')[0]);

            //L is the lower class boundary of the group containing the median - lowerBoundary
            //n is the total number of values - sum
            //B is the cumulative frequency of the groups before the median group - cumulativeFrequency
            //G is the frequency of the median group - (int)lowerBoundary.Population
            //w is the group width - width
            //MedianAge = L + (((n/2) - B) / G) * W

            median = (int)(lowerBoundary + (((sum/2) - cumulativeFrequency) / (int)medianGroup.Population) * width);

            return median;
        }

Он работает нормально, и я могу также получить среднее значение.Но я пытаюсь пересмотреть это с LINQ.Я не хочу держать это с заявлениями Continue и Break.

Может кто-нибудь предложить / пересмотреть вышесказанное?

1 Ответ

0 голосов
/ 04 марта 2019

Это определенно выглядит плохо:

 var population = dataList.Sum(x => x.pop);
 var aggregate = 0;
 var median = dataList
     .Select(x => new
     {
         split = x.Group.Split(" to "),
         pop   = (int)x.Population
     })
     .Select(x => new
     {
         from = int.Parse(x.split[0]),
         to   = int.Parse(x.split[1]),
         x.pop
     })
     //median calculation here VVVV
     .SelectMany(x=> 
         Enumerable
             .Range(x.from, x.to - x.from + 1)
             .Select(y=> new
             {
                 age = y,
                 pop = x.pop/(x.to - x.from + 1) //tail lost here, for small values will return incorrect values. Distribution through linq is bad idea here.
             })
      )
     .OrderBy(x => x.age)
     .First(x => (aggregate+= x.pop) >= population/2)
     .age;

PS : не проверялось это.Ваш подход через для хорош.Linq плохо использовать здесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...