在MongoDB中使用聚合(aggregate)計算四分位數(Quartile)
引用自維基百科
四分位數(Quartile)是統計學中分位數的一種,即把所有數值由小到大排列並分成四等份,處於三個分割點位置的數值就是四分位數。
假設有一個 numbers collection如下:
[
{
"values": [1, 2, 3, 4]
},
{
"values": [7, 15, 36, 39, 40, 41]
},
{
"values": [6, 7, 15, 36, 39, 40, 41, 42, 43, 47, 49]
}
]
以下是使用聚合(aggregate)計算四分位數:
db.getCollection("numbers").aggregate(
[
{
$addFields: {
count: { $size: '$values' }
}
},
{
$addFields: {
q1_1: { $floor: { $subtract: [ { $multiply: ['$count', 0.25] }, 0.25] } },
q1_2: { $floor: { $multiply: ['$count', 0.25] } },
q2_1: { $floor: { $subtract: [ { $multiply: ['$count', 0.5] }, 0.5] } },
q2_2: { $floor: { $multiply: ['$count', 0.5] } },
q3_1: { $floor: { $subtract: [ { $multiply: ['$count', 0.75] }, 0.25] } },
q3_2: { $floor: { $multiply: ['$count', 0.75] } },
min: { $arrayElemAt: ['$values', 0] },
max: { $arrayElemAt: ['$values', { $subtract: ['$count', 1] } ] }
}
},
{
$addFields: {
q1: { $avg: [ { $arrayElemAt: ['$values', '$q1_1'] }, { $arrayElemAt: ['$values', '$q1_2'] } ] },
q2: { $avg: [ { $arrayElemAt: ['$values', '$q2_1'] }, { $arrayElemAt: ['$values', '$q2_2'] } ] },
q3: { $avg: [ { $arrayElemAt: ['$values', '$q3_1'] }, { $arrayElemAt: ['$values', '$q3_2'] } ] }
}
},
{
$project: {
q1_1: false,
q1_2: false,
q2_1: false,
q2_2: false,
q3_1: false,
q3_2: false
}
}
]
);
執行結果:
程式碼說明:
- 用 $addFields 計算陣列長度,並存到 count 欄位
- 用 $addFields 計算Q1、Q2、Q3的兩個index以及最小值(min)與最大值(max)
- 用 $addFields 計算最終的Q1、Q2、Q3
- 用 $project 去除不需要用到的欄位
- 如果 count 大於0,則可以算出四分位數,如果等於0,則四分位數會是null。可以在最前面加一個stage用 $match 過濾掉陣列長度為0的資料,以免出現null的情況。
文章內容僅提供技術分享,如有錯誤還請不吝指教。