The fastest and easiest way to get max, min, mean from several objects

I need to find the value of max, min and mean (stats) of a list of objects that have their own statistics (statistics of the ResultGroup class based on all statistics of the results). When I add objects, the values ​​are easily updated, but if I change or delete one of them, I need to find the statistics again. There will usually be over 40,000 items, and I need it to be a quick operation.

Is there a better way than going through all the elements?

public class ResultGroup
{
    private Stats resultStats;
    //I need an updated stats
    public Stats ResultStats
    {
        get { return resultStats; }
    }
    private readonly ObservableCollection<Result> results = new ObservableCollection<Result>();

    public ObservableCollection<Result> Results
    {
        get
        {
            return results;
        }
    }
    public ResultGroup()
    {
        this.resultStats = new Stats();
        this.results.CollectionChanged += new NotifyCollectionChangedEventHandler(CollectionChanged);
    }

    private void CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == NotifyCollectionChangedAction.Add)
        {
            //It works ok on add.
            Stats lastResultStat = this.results[this.results.Count - 1].Stat;
            if (resultStats.Max < lastResultStat.Max)
                resultStats.Max = lastResultStat.Max;

            if (resultStats.Min > lastResultStat.Min)
                resultStats.Min = lastResultStat.Min;

            resultStats.Mean = (resultStats.Mean * (this.results.Count - 1) + lastResultStat.Mean) / this.results.Count;
        }
        else if (e.Action == NotifyCollectionChangedAction.Reset)
        {
            this.resultStats = StatsFactory();
        }
        else if (e.Action == NotifyCollectionChangedAction.Remove)
        {
            //Need to find the stats here
        }
        else if (e.Action == NotifyCollectionChangedAction.Replace)
        {
            //Need to find the stats here
        }
    }

    private Stats StatsFactory()
    {
        Stats dataStats = new Stats();
        dataStats.Max = float.MinValue;
        dataStats.Min = float.MaxValue;
        dataStats.Mean = 0;
        return dataStats;
    }
}

public class Result
{
    private float[] data;

    //Another class will fill data and set the Stats (max, min, mean)
    public float[] Data
    {
        get { return data; }
    }

    public Result(int lenght)
    {
        this.data = new float[lenght];
    }

    private Stats stat;
    public Stats Stat
    {
        get { return stat; }
        set { stat = value; }
    }
}

public class Stats
{
    public float Max { get; set; }
    public float Min { get; set; }
    public float Mean { get; set; }
}
+3
source share
5 answers

When deleting an element, you only need to iterate over all the elements when the deleted element is equal to the current min / max.

, min/max, /.

+3

LINQ, Min, Max Average CollectionChanged?

+1

, min , .

: , . , , . ( ), . , max min (, ). , . Max, Min, .

+1

?

as DB has indexing which can help. Also take a look at KDB or SAP HANA, where there is a Vertical / Column-based DB that seeps through millions of rows in milliseconds.

A simple file database such as SqlLite might help. (which will also help reduce memory usage if you are dealing with large amounts of data)

+1
source

// It is better to have a custom collection with the required properties inside the collection, and then install linq on top of the collection to save the aggregated values ​​...

 public class ObserCol: ObservableCollection<int>
{

    private int _maxValue = 0;

    public ObserCol() { 
        base.CollectionChanged +=new NotifyCollectionChangedEventHandler(CollectionChanged);
    }

    public int MaxValue{
        get {
            return _maxValue;
        }
    }

    private void CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == NotifyCollectionChangedAction.Add)
        {
            //Can use Linq to get the Max or Other Aggregate values..
        }
        else if (e.Action == NotifyCollectionChangedAction.Reset)
        {

        }
        else if (e.Action == NotifyCollectionChangedAction.Remove)
        {

        }
        else if (e.Action == NotifyCollectionChangedAction.Replace)
        {

        }
    }
}
0
source

All Articles