1
1
package org.jetbrains.kotlinx.dataframe.impl.aggregation.aggregators
2
2
3
+ import org.jetbrains.kotlinx.dataframe.api.skipNaNDefault
4
+ import org.jetbrains.kotlinx.dataframe.impl.aggregation.aggregators.aggregationHandlers.HybridAggregationHandler
3
5
import org.jetbrains.kotlinx.dataframe.impl.aggregation.aggregators.aggregationHandlers.ReducingAggregationHandler
4
6
import org.jetbrains.kotlinx.dataframe.impl.aggregation.aggregators.aggregationHandlers.SelectingAggregationHandler
5
7
import org.jetbrains.kotlinx.dataframe.impl.aggregation.aggregators.inputHandlers.AnyInputHandler
6
8
import org.jetbrains.kotlinx.dataframe.impl.aggregation.aggregators.inputHandlers.NumberInputHandler
7
9
import org.jetbrains.kotlinx.dataframe.impl.aggregation.aggregators.multipleColumnsHandlers.FlatteningMultipleColumnsHandler
8
10
import org.jetbrains.kotlinx.dataframe.impl.aggregation.aggregators.multipleColumnsHandlers.TwoStepMultipleColumnsHandler
9
11
import org.jetbrains.kotlinx.dataframe.math.indexOfMax
12
+ import org.jetbrains.kotlinx.dataframe.math.indexOfMedian
10
13
import org.jetbrains.kotlinx.dataframe.math.indexOfMin
11
14
import org.jetbrains.kotlinx.dataframe.math.maxOrNull
12
15
import org.jetbrains.kotlinx.dataframe.math.maxTypeConversion
13
16
import org.jetbrains.kotlinx.dataframe.math.mean
14
17
import org.jetbrains.kotlinx.dataframe.math.meanTypeConversion
15
- import org.jetbrains.kotlinx.dataframe.math.median
18
+ import org.jetbrains.kotlinx.dataframe.math.medianConversion
19
+ import org.jetbrains.kotlinx.dataframe.math.medianOrNull
16
20
import org.jetbrains.kotlinx.dataframe.math.minOrNull
17
21
import org.jetbrains.kotlinx.dataframe.math.minTypeConversion
18
22
import org.jetbrains.kotlinx.dataframe.math.percentile
@@ -29,13 +33,23 @@ internal object Aggregators {
29
33
private fun <Value : Return & Any , Return : Any ?> twoStepSelectingForAny (
30
34
getReturnType : CalculateReturnType ,
31
35
indexOfResult : IndexOfResult <Value >,
32
- stepOneReducer : Reducer <Value , Return >,
36
+ stepOneSelector : Selector <Value , Return >,
33
37
) = Aggregator (
34
- aggregationHandler = SelectingAggregationHandler (stepOneReducer , indexOfResult, getReturnType),
38
+ aggregationHandler = SelectingAggregationHandler (stepOneSelector , indexOfResult, getReturnType),
35
39
inputHandler = AnyInputHandler (),
36
40
multipleColumnsHandler = TwoStepMultipleColumnsHandler (),
37
41
)
38
42
43
+ private fun <Value : Any , Return : Any ?> flattenHybridForAny (
44
+ getReturnType : CalculateReturnType ,
45
+ indexOfResult : IndexOfResult <Value >,
46
+ reducer : Reducer <Value , Return >,
47
+ ) = Aggregator (
48
+ aggregationHandler = HybridAggregationHandler (reducer, indexOfResult, getReturnType),
49
+ inputHandler = AnyInputHandler (),
50
+ multipleColumnsHandler = FlatteningMultipleColumnsHandler (),
51
+ )
52
+
39
53
private fun <Value : Any , Return : Any ?> twoStepReducingForAny (
40
54
getReturnType : CalculateReturnType ,
41
55
stepOneReducer : Reducer <Value , Return >,
@@ -101,7 +115,7 @@ internal object Aggregators {
101
115
private val min by withOneOption { skipNaN: Boolean ->
102
116
twoStepSelectingForAny<Comparable <Any >, Comparable <Any >? > (
103
117
getReturnType = minTypeConversion,
104
- stepOneReducer = { type -> minOrNull(type, skipNaN) },
118
+ stepOneSelector = { type -> minOrNull(type, skipNaN) },
105
119
indexOfResult = { type -> indexOfMin(type, skipNaN) },
106
120
)
107
121
}
@@ -113,15 +127,15 @@ internal object Aggregators {
113
127
private val max by withOneOption { skipNaN: Boolean ->
114
128
twoStepSelectingForAny<Comparable <Any >, Comparable <Any >? > (
115
129
getReturnType = maxTypeConversion,
116
- stepOneReducer = { type -> maxOrNull(type, skipNaN) },
130
+ stepOneSelector = { type -> maxOrNull(type, skipNaN) },
117
131
indexOfResult = { type -> indexOfMax(type, skipNaN) },
118
132
)
119
133
}
120
134
121
135
// T: Number? -> Double
122
- val std by withTwoOptions { skipNA : Boolean , ddof: Int ->
136
+ val std by withTwoOptions { skipNaN : Boolean , ddof: Int ->
123
137
flattenReducingForNumbers(stdTypeConversion) { type ->
124
- std(type, skipNA , ddof)
138
+ std(type, skipNaN , ddof)
125
139
}
126
140
}
127
141
@@ -140,9 +154,31 @@ internal object Aggregators {
140
154
}
141
155
}
142
156
143
- // T: Comparable<T>? -> T
144
- val median by flattenReducingForAny<Comparable <Any ?>> { type ->
145
- asIterable().median(type)
157
+ // T : primitive Number? -> Double?
158
+ // T : Comparable<T & Any>? -> T?
159
+ fun <T > medianCommon (skipNaN : Boolean ): Aggregator <T & Any , T ?>
160
+ where T : Comparable <T & Any >? =
161
+ median.invoke(skipNaN).cast2()
162
+
163
+ // T : Comparable<T & Any>? -> T?
164
+ fun <T > medianComparables (): Aggregator <T & Any , T ?>
165
+ where T : Comparable <T & Any >? =
166
+ medianCommon<T >(skipNaNDefault).cast2()
167
+
168
+ // T : primitive Number? -> Double?
169
+ fun <T > medianNumbers (
170
+ skipNaN : Boolean ,
171
+ ): Aggregator <T & Any , Double ?>
172
+ where T : Comparable <T & Any >? , T : Number ? =
173
+ medianCommon<T >(skipNaN).cast2()
174
+
175
+ @Suppress(" UNCHECKED_CAST" )
176
+ private val median by withOneOption { skipNaN: Boolean ->
177
+ flattenHybridForAny<Comparable <Any >, Comparable <Any >? > (
178
+ getReturnType = medianConversion,
179
+ reducer = { type -> medianOrNull(type, skipNaN) as Comparable <Any >? },
180
+ indexOfResult = { type -> indexOfMedian(type, skipNaN) },
181
+ )
146
182
}
147
183
148
184
// T: Number -> T
0 commit comments