-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add QgsStatisticalSummary class for calculating stats from a list
of values.
- Loading branch information
1 parent
bb0e583
commit 154468b
Showing
7 changed files
with
504 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
/** \ingroup core | ||
* \class QgsStatisticalSummary | ||
* \brief Calculator for summary statistics for a list of doubles. | ||
* | ||
* Statistics are calculated by calling @link calculate @endlink and passing a list of doubles. The | ||
* individual statistics can then be retrieved using the associated methods. Note that not all statistics | ||
* are calculated by default. Statistics which require slower computations are only calculated by | ||
* specifying the statistic in the constructor or via @link setStatistics @endlink. | ||
* | ||
* \note Added in version 2.9 | ||
*/ | ||
|
||
class QgsStatisticalSummary | ||
{ | ||
%TypeHeaderCode | ||
#include <qgsstatisticalsummary.h> | ||
%End | ||
|
||
public: | ||
|
||
//! Enumeration of flags that specify statistics to be calculated | ||
enum Statistic | ||
{ | ||
Count , //!< Count | ||
Sum, //!< Sum of values | ||
Mean, //!< Mean of values | ||
Median, //!< Median of values | ||
StDev, //!< Standard deviation of values | ||
StDevSample, //!< Sample standard deviation of values | ||
Min, //!< Min of values | ||
Max, //!< Max of values | ||
Range, //!< Range of values (max - min) | ||
Minority, //!< Minority of values | ||
Majority, //!< Majority of values | ||
Variety, //!< Variety (count of distinct) values | ||
All | ||
}; | ||
|
||
typedef QFlags<QgsStatisticalSummary::Statistic> Statistics; | ||
|
||
/** Constructor for QgsStatisticalSummary | ||
* @param stats flags for statistics to calculate | ||
*/ | ||
QgsStatisticalSummary( QgsStatisticalSummary::Statistics stats = QgsStatisticalSummary::Statistics( 0 ) ); | ||
|
||
virtual ~QgsStatisticalSummary(); | ||
|
||
/** Returns flags which specify which statistics will be calculated. Some statistics | ||
* are always calculated (eg sum, min and max). | ||
* @see setStatistics | ||
*/ | ||
QgsStatisticalSummary::Statistics statistics() const; | ||
|
||
/** Sets flags which specify which statistics will be calculated. Some statistics | ||
* are always calculated (eg sum, min and max). | ||
* @param stats flags for statistics to calculate | ||
* @see statistics | ||
*/ | ||
void setStatistics( QgsStatisticalSummary::Statistics stats ); | ||
|
||
/** Resets the calculated values | ||
*/ | ||
void reset(); | ||
|
||
/** Calculates summary statistics for a list of values | ||
* @param values list of doubles | ||
*/ | ||
void calculate( const QList<double>& values ); | ||
|
||
/** Returns calculated count of values | ||
*/ | ||
int count() const; | ||
|
||
/** Returns calculated sum of values | ||
*/ | ||
double sum() const; | ||
|
||
/** Returns calculated mean of values | ||
*/ | ||
double mean() const; | ||
|
||
/** Returns calculated median of values. This is only calculated if Statistic::Median has | ||
* been specified in the constructor or via setStatistics. | ||
*/ | ||
double median() const; | ||
|
||
/** Returns calculated minimum from values. | ||
*/ | ||
double min() const; | ||
|
||
/** Returns calculated maximum from values. | ||
*/ | ||
double max() const; | ||
|
||
/** Returns calculated range (difference between maximum and minimum values). | ||
*/ | ||
double range() const; | ||
|
||
/** Returns population standard deviation. This is only calculated if Statistic::StDev has | ||
* been specified in the constructor or via setStatistics. | ||
* @see sampleStDev | ||
*/ | ||
double stDev() const; | ||
|
||
/** Returns sample standard deviation. This is only calculated if Statistic::StDev has | ||
* been specified in the constructor or via setStatistics. | ||
* @see stDev | ||
*/ | ||
double sampleStDev() const; | ||
|
||
/** Returns variety of values. The variety is the count of unique values from the list. | ||
* This is only calculated if Statistic::Variety has been specified in the constructor | ||
* or via setStatistics. | ||
*/ | ||
int variety() const; | ||
|
||
/** Returns minority of values. The minority is the value with least occurances in the list | ||
* This is only calculated if Statistic::Minority has been specified in the constructor | ||
* or via setStatistics. | ||
* @see majority | ||
*/ | ||
double minority() const; | ||
|
||
/** Returns majority of values. The majority is the value with most occurances in the list | ||
* This is only calculated if Statistic::Majority has been specified in the constructor | ||
* or via setStatistics. | ||
* @see minority | ||
*/ | ||
double majority() const; | ||
|
||
}; | ||
|
||
QFlags<QgsStatisticalSummary::Statistic> operator|(QgsStatisticalSummary::Statistic f1, QFlags<QgsStatisticalSummary::Statistic> f2); | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
/*************************************************************************** | ||
qgsstatisticalsummary.cpp | ||
-------------------------------------- | ||
Date : May 2015 | ||
Copyright : (C) 2015 by Nyall Dawson | ||
Email : nyall dot dawson at gmail dot com | ||
*************************************************************************** | ||
* * | ||
* This program is free software; you can redistribute it and/or modify * | ||
* it under the terms of the GNU General Public License as published by * | ||
* the Free Software Foundation; either version 2 of the License, or * | ||
* (at your option) any later version. * | ||
* * | ||
***************************************************************************/ | ||
|
||
#include "qgsstatisticalsummary.h" | ||
#include <limits> | ||
#include <qmath.h> | ||
|
||
|
||
QgsStatisticalSummary::QgsStatisticalSummary( Statistics stats ) | ||
: mStatistics( stats ) | ||
{ | ||
reset(); | ||
} | ||
|
||
QgsStatisticalSummary::~QgsStatisticalSummary() | ||
{ | ||
|
||
} | ||
|
||
void QgsStatisticalSummary::reset() | ||
{ | ||
mCount = 0; | ||
mSum = 0; | ||
mMean = 0; | ||
mMedian = 0; | ||
mMin = std::numeric_limits<double>::max(); | ||
mMax = std::numeric_limits<double>::min(); | ||
mStdev = 0; | ||
mSampleStdev = 0; | ||
mMinority = 0; | ||
mMajority = 0; | ||
mValueCount.clear(); | ||
} | ||
|
||
void QgsStatisticalSummary::calculate( const QList<double> &values ) | ||
{ | ||
reset(); | ||
|
||
foreach ( double value, values ) | ||
{ | ||
mCount++; | ||
mSum += value; | ||
mMin = qMin( mMin, value ); | ||
mMax = qMax( mMax, value ); | ||
|
||
if ( mStatistics & QgsStatisticalSummary::Majority || mStatistics & QgsStatisticalSummary::Minority || mStatistics & QgsStatisticalSummary::Variety ) | ||
mValueCount.insert( value, mValueCount.value( value, 0 ) + 1 ); | ||
} | ||
|
||
if ( mCount == 0 ) | ||
return; | ||
|
||
mMean = mSum / mCount; | ||
|
||
if ( mStatistics & QgsStatisticalSummary::StDev ) | ||
{ | ||
double sumSquared = 0; | ||
foreach ( double value, values ) | ||
{ | ||
double diff = value - mMean; | ||
sumSquared += diff * diff; | ||
} | ||
mStdev = qPow( sumSquared / values.count(), 0.5 ); | ||
mSampleStdev = qPow( sumSquared / ( values.count() - 1 ), 0.5 ); | ||
} | ||
|
||
if ( mStatistics & QgsStatisticalSummary::Median ) | ||
{ | ||
QList<double> sorted = values; | ||
qSort( sorted.begin(), sorted.end() ); | ||
bool even = ( mCount % 2 ) < 1; | ||
if ( even ) | ||
{ | ||
mMedian = ( sorted[mCount / 2 - 1] + sorted[mCount / 2] ) / 2.0; | ||
} | ||
else //odd | ||
{ | ||
mMedian = sorted[( mCount + 1 ) / 2 - 1]; | ||
} | ||
} | ||
|
||
if ( mStatistics & QgsStatisticalSummary::Minority || mStatistics & QgsStatisticalSummary::Majority ) | ||
{ | ||
QList<int> valueCounts = mValueCount.values(); | ||
qSort( valueCounts.begin(), valueCounts.end() ); | ||
if ( mStatistics & QgsStatisticalSummary::Minority ) | ||
{ | ||
mMinority = mValueCount.key( valueCounts.first() ); | ||
} | ||
if ( mStatistics & QgsStatisticalSummary::Majority ) | ||
{ | ||
mMajority = mValueCount.key( valueCounts.last() ); | ||
} | ||
} | ||
|
||
} | ||
|
Oops, something went wrong.