mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-17 00:04:02 -04:00
Allow QgsStatisticalSummary to calculate first/last value
Trivial, but simplifies other code which desires to expose a choice between first/last/min/max/mean/etc...
This commit is contained in:
parent
5586352a13
commit
5f817b4db3
@ -46,6 +46,8 @@ specifying the statistic in the constructor or via setStatistics().
|
|||||||
FirstQuartile,
|
FirstQuartile,
|
||||||
ThirdQuartile,
|
ThirdQuartile,
|
||||||
InterQuartileRange,
|
InterQuartileRange,
|
||||||
|
First,
|
||||||
|
Last,
|
||||||
All
|
All
|
||||||
};
|
};
|
||||||
typedef QFlags<QgsStatisticalSummary::Statistic> Statistics;
|
typedef QFlags<QgsStatisticalSummary::Statistic> Statistics;
|
||||||
@ -214,6 +216,24 @@ be calculated.
|
|||||||
%Docstring
|
%Docstring
|
||||||
Returns calculated range (difference between maximum and minimum values). A NaN value may be returned if the range cannot
|
Returns calculated range (difference between maximum and minimum values). A NaN value may be returned if the range cannot
|
||||||
be calculated.
|
be calculated.
|
||||||
|
%End
|
||||||
|
|
||||||
|
double first() const;
|
||||||
|
%Docstring
|
||||||
|
Returns the first value obtained. A NaN value may be returned if no values were encountered.
|
||||||
|
|
||||||
|
.. seealso:: :py:func:`last`
|
||||||
|
|
||||||
|
.. versionadded:: 3.6
|
||||||
|
%End
|
||||||
|
|
||||||
|
double last() const;
|
||||||
|
%Docstring
|
||||||
|
Returns the last value obtained. A NaN value may be returned if no values were encountered.
|
||||||
|
|
||||||
|
.. seealso:: :py:func:`first`
|
||||||
|
|
||||||
|
.. versionadded:: 3.6
|
||||||
%End
|
%End
|
||||||
|
|
||||||
double stDev() const;
|
double stDev() const;
|
||||||
|
@ -32,6 +32,8 @@ QgsStatisticalSummary::QgsStatisticalSummary( Statistics stats )
|
|||||||
|
|
||||||
void QgsStatisticalSummary::reset()
|
void QgsStatisticalSummary::reset()
|
||||||
{
|
{
|
||||||
|
mFirst = std::numeric_limits<double>::quiet_NaN();
|
||||||
|
mLast = std::numeric_limits<double>::quiet_NaN();
|
||||||
mCount = 0;
|
mCount = 0;
|
||||||
mMissing = 0;
|
mMissing = 0;
|
||||||
mSum = 0;
|
mSum = 0;
|
||||||
@ -59,7 +61,7 @@ void QgsStatisticalSummary::calculate( const QList<double> &values )
|
|||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
Q_FOREACH ( double value, values )
|
for ( double value : values )
|
||||||
{
|
{
|
||||||
addValue( value );
|
addValue( value );
|
||||||
}
|
}
|
||||||
@ -69,10 +71,13 @@ void QgsStatisticalSummary::calculate( const QList<double> &values )
|
|||||||
|
|
||||||
void QgsStatisticalSummary::addValue( double value )
|
void QgsStatisticalSummary::addValue( double value )
|
||||||
{
|
{
|
||||||
|
if ( mCount == 0 )
|
||||||
|
mFirst = value;
|
||||||
mCount++;
|
mCount++;
|
||||||
mSum += value;
|
mSum += value;
|
||||||
mMin = std::min( mMin, value );
|
mMin = std::min( mMin, value );
|
||||||
mMax = std::max( mMax, value );
|
mMax = std::max( mMax, value );
|
||||||
|
mLast = value;
|
||||||
|
|
||||||
if ( mStatistics & QgsStatisticalSummary::Majority || mStatistics & QgsStatisticalSummary::Minority || mStatistics & QgsStatisticalSummary::Variety )
|
if ( mStatistics & QgsStatisticalSummary::Majority || mStatistics & QgsStatisticalSummary::Minority || mStatistics & QgsStatisticalSummary::Variety )
|
||||||
mValueCount.insert( value, mValueCount.value( value, 0 ) + 1 );
|
mValueCount.insert( value, mValueCount.value( value, 0 ) + 1 );
|
||||||
@ -102,6 +107,8 @@ void QgsStatisticalSummary::finalize()
|
|||||||
{
|
{
|
||||||
if ( mCount == 0 )
|
if ( mCount == 0 )
|
||||||
{
|
{
|
||||||
|
mFirst = std::numeric_limits<double>::quiet_NaN();
|
||||||
|
mLast = std::numeric_limits<double>::quiet_NaN();
|
||||||
mMin = std::numeric_limits<double>::quiet_NaN();
|
mMin = std::numeric_limits<double>::quiet_NaN();
|
||||||
mMax = std::numeric_limits<double>::quiet_NaN();
|
mMax = std::numeric_limits<double>::quiet_NaN();
|
||||||
mMean = std::numeric_limits<double>::quiet_NaN();
|
mMean = std::numeric_limits<double>::quiet_NaN();
|
||||||
@ -266,6 +273,10 @@ double QgsStatisticalSummary::statistic( QgsStatisticalSummary::Statistic stat )
|
|||||||
return mThirdQuartile;
|
return mThirdQuartile;
|
||||||
case InterQuartileRange:
|
case InterQuartileRange:
|
||||||
return mThirdQuartile - mFirstQuartile;
|
return mThirdQuartile - mFirstQuartile;
|
||||||
|
case First:
|
||||||
|
return mFirst;
|
||||||
|
case Last:
|
||||||
|
return mLast;
|
||||||
case All:
|
case All:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -308,6 +319,10 @@ QString QgsStatisticalSummary::displayName( QgsStatisticalSummary::Statistic sta
|
|||||||
return QObject::tr( "Q3" );
|
return QObject::tr( "Q3" );
|
||||||
case InterQuartileRange:
|
case InterQuartileRange:
|
||||||
return QObject::tr( "IQR" );
|
return QObject::tr( "IQR" );
|
||||||
|
case First:
|
||||||
|
return QObject::tr( "First" );
|
||||||
|
case Last:
|
||||||
|
return QObject::tr( "Last" );
|
||||||
case All:
|
case All:
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
@ -47,23 +47,25 @@ class CORE_EXPORT QgsStatisticalSummary
|
|||||||
//! Enumeration of flags that specify statistics to be calculated
|
//! Enumeration of flags that specify statistics to be calculated
|
||||||
enum Statistic
|
enum Statistic
|
||||||
{
|
{
|
||||||
Count = 1, //!< Count
|
Count = 1 << 0, //!< Count
|
||||||
CountMissing = 32770, //!< Number of missing (null) values
|
CountMissing = 1 << 15, //!< Number of missing (null) values
|
||||||
Sum = 2, //!< Sum of values
|
Sum = 1 << 1, //!< Sum of values
|
||||||
Mean = 4, //!< Mean of values
|
Mean = 1 << 2, //!< Mean of values
|
||||||
Median = 8, //!< Median of values
|
Median = 1 << 3, //!< Median of values
|
||||||
StDev = 16, //!< Standard deviation of values
|
StDev = 1 << 4, //!< Standard deviation of values
|
||||||
StDevSample = 32, //!< Sample standard deviation of values
|
StDevSample = 1 << 5, //!< Sample standard deviation of values
|
||||||
Min = 64, //!< Min of values
|
Min = 1 << 6, //!< Min of values
|
||||||
Max = 128, //!< Max of values
|
Max = 1 << 7, //!< Max of values
|
||||||
Range = 256, //!< Range of values (max - min)
|
Range = 1 << 8, //!< Range of values (max - min)
|
||||||
Minority = 512, //!< Minority of values
|
Minority = 1 << 9, //!< Minority of values
|
||||||
Majority = 1024, //!< Majority of values
|
Majority = 1 << 10, //!< Majority of values
|
||||||
Variety = 2048, //!< Variety (count of distinct) values
|
Variety = 1 << 11, //!< Variety (count of distinct) values
|
||||||
FirstQuartile = 4096, //!< First quartile
|
FirstQuartile = 1 << 12, //!< First quartile
|
||||||
ThirdQuartile = 8192, //!< Third quartile
|
ThirdQuartile = 1 << 13, //!< Third quartile
|
||||||
InterQuartileRange = 16384, //!< Inter quartile range (IQR)
|
InterQuartileRange = 1 << 14, //!< Inter quartile range (IQR)
|
||||||
All = Count | CountMissing | Sum | Mean | Median | StDev | Max | Min | Range | Minority | Majority | Variety | FirstQuartile | ThirdQuartile | InterQuartileRange
|
First = 1 << 16, //!< First value (since QGIS 3.6)
|
||||||
|
Last = 1 << 17, //!< Last value (since QGIS 3.6)
|
||||||
|
All = Count | CountMissing | Sum | Mean | Median | StDev | Max | Min | Range | Minority | Majority | Variety | FirstQuartile | ThirdQuartile | InterQuartileRange | First | Last
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS( Statistics, Statistic )
|
Q_DECLARE_FLAGS( Statistics, Statistic )
|
||||||
|
|
||||||
@ -199,6 +201,22 @@ class CORE_EXPORT QgsStatisticalSummary
|
|||||||
*/
|
*/
|
||||||
double range() const { return std::isnan( mMax ) || std::isnan( mMin ) ? std::numeric_limits<double>::quiet_NaN() : mMax - mMin; }
|
double range() const { return std::isnan( mMax ) || std::isnan( mMin ) ? std::numeric_limits<double>::quiet_NaN() : mMax - mMin; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the first value obtained. A NaN value may be returned if no values were encountered.
|
||||||
|
*
|
||||||
|
* \see last()
|
||||||
|
* \since QGIS 3.6
|
||||||
|
*/
|
||||||
|
double first() const { return mFirst; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the last value obtained. A NaN value may be returned if no values were encountered.
|
||||||
|
*
|
||||||
|
* \see first()
|
||||||
|
* \since QGIS 3.6
|
||||||
|
*/
|
||||||
|
double last() const { return mLast; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns population standard deviation. This is only calculated if Statistic::StDev has
|
* Returns population standard deviation. This is only calculated if Statistic::StDev has
|
||||||
* been specified in the constructor or via setStatistics. A NaN value may be returned if the standard deviation cannot
|
* been specified in the constructor or via setStatistics. A NaN value may be returned if the standard deviation cannot
|
||||||
@ -290,6 +308,8 @@ class CORE_EXPORT QgsStatisticalSummary
|
|||||||
double mMajority;
|
double mMajority;
|
||||||
double mFirstQuartile;
|
double mFirstQuartile;
|
||||||
double mThirdQuartile;
|
double mThirdQuartile;
|
||||||
|
double mFirst;
|
||||||
|
double mLast;
|
||||||
QMap< double, int > mValueCount;
|
QMap< double, int > mValueCount;
|
||||||
QList< double > mValues;
|
QList< double > mValues;
|
||||||
};
|
};
|
||||||
|
@ -85,6 +85,10 @@ void TestQgsStatisticSummary::stats()
|
|||||||
QCOMPARE( s2.sum(), 24.0 );
|
QCOMPARE( s2.sum(), 24.0 );
|
||||||
QCOMPARE( s.mean(), 4.0 );
|
QCOMPARE( s.mean(), 4.0 );
|
||||||
QCOMPARE( s2.mean(), 4.0 );
|
QCOMPARE( s2.mean(), 4.0 );
|
||||||
|
QCOMPARE( s.first(), 4.0 );
|
||||||
|
QCOMPARE( s2.first(), 4.0 );
|
||||||
|
QCOMPARE( s.last(), 8.0 );
|
||||||
|
QCOMPARE( s2.last(), 8.0 );
|
||||||
QGSCOMPARENEAR( s.stDev(), 2.0816, 0.0001 );
|
QGSCOMPARENEAR( s.stDev(), 2.0816, 0.0001 );
|
||||||
QGSCOMPARENEAR( s2.stDev(), 2.0816, 0.0001 );
|
QGSCOMPARENEAR( s2.stDev(), 2.0816, 0.0001 );
|
||||||
QGSCOMPARENEAR( s.sampleStDev(), 2.2803, 0.0001 );
|
QGSCOMPARENEAR( s.sampleStDev(), 2.2803, 0.0001 );
|
||||||
@ -227,6 +231,8 @@ void TestQgsStatisticSummary::individualStatCalculations_data()
|
|||||||
QTest::newRow( "third_quartile" ) << ( int )QgsStatisticalSummary::ThirdQuartile << 5.0;
|
QTest::newRow( "third_quartile" ) << ( int )QgsStatisticalSummary::ThirdQuartile << 5.0;
|
||||||
QTest::newRow( "iqr" ) << ( int )QgsStatisticalSummary::InterQuartileRange << 2.0;
|
QTest::newRow( "iqr" ) << ( int )QgsStatisticalSummary::InterQuartileRange << 2.0;
|
||||||
QTest::newRow( "missing" ) << ( int )QgsStatisticalSummary::CountMissing << 0.0;
|
QTest::newRow( "missing" ) << ( int )QgsStatisticalSummary::CountMissing << 0.0;
|
||||||
|
QTest::newRow( "first" ) << static_cast< int >( QgsStatisticalSummary::First ) << 4.0;
|
||||||
|
QTest::newRow( "last" ) << static_cast< int >( QgsStatisticalSummary::Last ) << 8.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestQgsStatisticSummary::individualStatCalculations()
|
void TestQgsStatisticSummary::individualStatCalculations()
|
||||||
@ -311,6 +317,10 @@ void TestQgsStatisticSummary::noValues()
|
|||||||
QCOMPARE( s.statistic( QgsStatisticalSummary::CountMissing ), 0.0 );
|
QCOMPARE( s.statistic( QgsStatisticalSummary::CountMissing ), 0.0 );
|
||||||
QCOMPARE( s.sum(), 0.0 );
|
QCOMPARE( s.sum(), 0.0 );
|
||||||
QCOMPARE( s.statistic( QgsStatisticalSummary::Sum ), 0.0 );
|
QCOMPARE( s.statistic( QgsStatisticalSummary::Sum ), 0.0 );
|
||||||
|
QVERIFY( std::isnan( s.first() ) );
|
||||||
|
QVERIFY( std::isnan( s.statistic( QgsStatisticalSummary::First ) ) );
|
||||||
|
QVERIFY( std::isnan( s.last() ) );
|
||||||
|
QVERIFY( std::isnan( s.statistic( QgsStatisticalSummary::Last ) ) );
|
||||||
QVERIFY( std::isnan( s.mean() ) );
|
QVERIFY( std::isnan( s.mean() ) );
|
||||||
QVERIFY( std::isnan( s.statistic( QgsStatisticalSummary::Mean ) ) );
|
QVERIFY( std::isnan( s.statistic( QgsStatisticalSummary::Mean ) ) );
|
||||||
QVERIFY( std::isnan( s.median() ) );
|
QVERIFY( std::isnan( s.median() ) );
|
||||||
|
Loading…
x
Reference in New Issue
Block a user