Simple histogram generation of integer data in C#

后端 未结 4 1508
花落未央
花落未央 2020-12-31 19:44

As part of a test bench I\'m building, I\'m looking for a simple class to calculate a histogram of integer values (number of iterations taken for an algorithm to solve a pro

相关标签:
4条回答
  • 2020-12-31 19:50

    You can use Linq:

    var items = new[] {5, 6, 1, 2, 3, 1, 5, 2};
    items
        .GroupBy(i => i)
        .Select(g => new {
            Item = g.Key,
            Count = g.Count()
        })
        .OrderBy(g => g.Item)
        .ToList()
        .ForEach(g => {
            Console.WriteLine("{0} occurred {1} times", g.Item, g.Count);
        });
    
    0 讨论(0)
  • 2020-12-31 19:51

    You could use SortedDictionary

    uint[] items = new uint[] {5, 6, 1, 2, 3, 1, 5, 2}; // sample data
    SortedDictionary<uint, int> histogram = new SortedDictionary<uint, int>();
    foreach (uint item in items) {
        if (histogram.ContainsKey(item)) {
            histogram[item]++;
        } else {
            histogram[item] = 1;
        }
    }
    foreach (KeyValuePair<uint, int> pair in histogram) {
        Console.WriteLine("{0} occurred {1} times", pair.Key, pair.Value);
    }
    

    This will leave out empty bins, though

    0 讨论(0)
  • 2020-12-31 20:01

    My implementation of a simple extension method to create a histogram:

    public static IReadOnlyDictionary<T, int> ToHistogram<T>(this IEnumerable<T> enumerable)
       => enumerable.GroupBy(item => item).ToDictionary(grouping => grouping.Key, grouping => grouping.Count());
    
    0 讨论(0)
  • 2020-12-31 20:11

    Based on BastardSaint's suggestion I came up with a neat and fairly generic wrapper:

    public class Histogram<TVal> : SortedDictionary<TVal, uint>
    {
        public void IncrementCount(TVal binToIncrement)
        {
            if (ContainsKey(binToIncrement))
            {
                this[binToIncrement]++;
            }
            else
            {
                Add(binToIncrement, 1);
            }
        }
    }
    

    So now I can do:

    const uint numOfInputDataPoints = 5;
    Histogram<uint> hist = new Histogram<uint>();
    
    // Fill the histogram with data
    for (uint i = 0; i < numOfInputDataPoints; i++)
    {
        // Grab a result from my algorithm
        uint numOfIterationsForSolution = MyAlorithm.Run();
    
        // Add the number to the histogram
        hist.IncrementCount( numOfIterationsForSolution );
    }
    
    // Report the results
    foreach (KeyValuePair<uint, uint> histEntry in hist.AsEnumerable())
    {
        Console.WriteLine("{0} occurred {1} times", histEntry.Key, histEntry.Value);
    }
    

    Took me a while to work out how to make it generic (to begin with I just overrode the SortedDictionary constructor which meant you could only use it for uint keys).

    0 讨论(0)
提交回复
热议问题