11package org.jetbrains.kotlinx.dataframe.math
22
3- import org.jetbrains.kotlinx.dataframe.api.isNaN
43import org.jetbrains.kotlinx.dataframe.api.skipNA_default
54import org.jetbrains.kotlinx.dataframe.impl.api.toBigDecimal
65import org.jetbrains.kotlinx.dataframe.impl.convertToUnifiedNumberType
@@ -13,52 +12,53 @@ import kotlin.reflect.KType
1312import kotlin.reflect.full.withNullability
1413import kotlin.reflect.typeOf
1514
16- /* * @include [Sequence.mean ] */
15+ /* * @include [Sequence.meanOrNull ] */
1716@PublishedApi
18- internal fun <T : Number > Iterable<T>.mean (type : KType , skipNA : Boolean = skipNA_default): Number ? =
19- asSequence().mean (type, skipNA)
17+ internal fun <T : Number > Iterable<T>.meanOrNull (type : KType , skipNA : Boolean = skipNA_default): Number ? =
18+ asSequence().meanOrNull (type, skipNA)
2019
2120/* *
2221 * Returns the mean of the numbers in [this].
2322 *
2423 * If the input is empty, the return value will be `null`.
2524 *
2625 * If the [type] given or input consists of only [Int], [Short], [Byte], [Long], [Double], or [Float],
27- * the return type will be [Double]`?` (Never `NaN`) .
26+ * the return type will be [Double].
2827 *
29- * If the [type] given or the input contains [BigInteger] or [BigDecimal], the return type will be [BigDecimal]`?`.
28+ * If the [type] given or the input contains [BigInteger] or [BigDecimal],
29+ * the return type will be [BigDecimal].
3030 * @param type The type of the numbers in the sequence.
3131 * @param skipNA Whether to skip `NaN` values (default: `false`). Only relevant for [Double] and [Float].
3232 */
3333@Suppress(" UNCHECKED_CAST" )
34- internal fun <T : Number > Sequence<T>.mean (type : KType , skipNA : Boolean = skipNA_default): Number ? {
34+ internal fun <T : Number > Sequence<T>.meanOrNull (type : KType , skipNA : Boolean = skipNA_default): Number ? {
3535 if (type.isMarkedNullable) {
36- return filterNotNull().mean (type.withNullability(false ), skipNA)
36+ return filterNotNull().meanOrNull (type.withNullability(false ), skipNA)
3737 }
3838 return when (type.classifier) {
39- // Double -> Double?
40- Double ::class -> (this as Sequence <Double >).mean (skipNA). takeUnless { it.isNaN }
39+ // Double -> Double
40+ Double ::class -> (this as Sequence <Double >).meanOrNull (skipNA)
4141
42- // Float -> Double?
43- Float ::class -> (this as Sequence <Float >).mean (skipNA). takeUnless { it.isNaN }
42+ // Float -> Double
43+ Float ::class -> (this as Sequence <Float >).meanOrNull (skipNA)
4444
45- // Int -> Double?
46- Int ::class -> (this as Sequence <Int >).map { it.toDouble() }.mean (false ). takeUnless { it.isNaN }
45+ // Int -> Double
46+ Int ::class -> (this as Sequence <Int >).map { it.toDouble() }.meanOrNull (false )
4747
48- // Short -> Double?
49- Short ::class -> (this as Sequence <Short >).map { it.toDouble() }.mean (false ). takeUnless { it.isNaN }
48+ // Short -> Double
49+ Short ::class -> (this as Sequence <Short >).map { it.toDouble() }.meanOrNull (false )
5050
51- // Byte -> Double?
52- Byte ::class -> (this as Sequence <Byte >).map { it.toDouble() }.mean (false ). takeUnless { it.isNaN }
51+ // Byte -> Double
52+ Byte ::class -> (this as Sequence <Byte >).map { it.toDouble() }.meanOrNull (false )
5353
54- // Long -> Double?
55- Long ::class -> (this as Sequence <Long >).map { it.toDouble() }.mean (false ). takeUnless { it.isNaN }
54+ // Long -> Double
55+ Long ::class -> (this as Sequence <Long >).map { it.toDouble() }.meanOrNull (false )
5656
57- // BigInteger -> BigDecimal?
58- BigInteger ::class -> (this as Sequence <BigInteger >).mean ()
57+ // BigInteger -> BigDecimal
58+ BigInteger ::class -> (this as Sequence <BigInteger >).meanOrNull ()
5959
60- // BigDecimal -> BigDecimal?
61- BigDecimal ::class -> (this as Sequence <BigDecimal >).mean ()
60+ // BigDecimal -> BigDecimal
61+ BigDecimal ::class -> (this as Sequence <BigDecimal >).meanOrNull ()
6262
6363 // Number -> Conversion(Common number type) -> Number? (Double or BigDecimal?)
6464 // fallback case, heavy as it needs to collect all types at runtime
@@ -69,7 +69,7 @@ internal fun <T : Number> Sequence<T>.mean(type: KType, skipNA: Boolean = skipNA
6969 error(" Cannot find unified number type for $numberTypes " )
7070 }
7171 this .convertToUnifiedNumberType(unifiedType)
72- .mean (unifiedType, skipNA)
72+ .meanOrNull (unifiedType, skipNA)
7373 }
7474
7575 // this means the sequence is empty
@@ -79,43 +79,43 @@ internal fun <T : Number> Sequence<T>.mean(type: KType, skipNA: Boolean = skipNA
7979 }
8080}
8181
82- internal fun Sequence<Double>.mean (skipNA : Boolean = skipNA_default): Double {
82+ internal fun Sequence<Double>.meanOrNull (skipNA : Boolean = skipNA_default): Double? {
8383 var count = 0
8484 var sum: Double = 0 .toDouble()
8585 for (element in this ) {
8686 if (element.isNaN()) {
8787 if (skipNA) {
8888 continue
8989 } else {
90- return Double . NaN
90+ return null
9191 }
9292 }
9393 sum + = element
9494 count++
9595 }
96- return if (count > 0 ) sum / count else Double . NaN
96+ return if (count > 0 ) sum / count else null
9797}
9898
9999@JvmName(" meanFloat" )
100- internal fun Sequence<Float>.mean (skipNA : Boolean = skipNA_default): Double {
100+ internal fun Sequence<Float>.meanOrNull (skipNA : Boolean = skipNA_default): Double? {
101101 var count = 0
102102 var sum: Double = 0 .toDouble()
103103 for (element in this ) {
104104 if (element.isNaN()) {
105105 if (skipNA) {
106106 continue
107107 } else {
108- return Double . NaN
108+ return null
109109 }
110110 }
111111 sum + = element
112112 count++
113113 }
114- return if (count > 0 ) sum / count else Double . NaN
114+ return if (count > 0 ) sum / count else null
115115}
116116
117117@JvmName(" bigIntegerMean" )
118- internal fun Sequence<BigInteger>.mean (): BigDecimal ? {
118+ internal fun Sequence<BigInteger>.meanOrNull (): BigDecimal ? {
119119 var count = 0
120120 val sum = sumOf {
121121 count++
@@ -125,7 +125,7 @@ internal fun Sequence<BigInteger>.mean(): BigDecimal? {
125125}
126126
127127@JvmName(" bigDecimalMean" )
128- internal fun Sequence<BigDecimal>.mean (): BigDecimal ? {
128+ internal fun Sequence<BigDecimal>.meanOrNull (): BigDecimal ? {
129129 var count = 0
130130 val sum = sumOf {
131131 count++
@@ -135,65 +135,65 @@ internal fun Sequence<BigDecimal>.mean(): BigDecimal? {
135135}
136136
137137@JvmName(" doubleMean" )
138- internal fun Iterable<Double>.mean (skipNA : Boolean = skipNA_default): Double = asSequence().mean (skipNA)
138+ internal fun Iterable<Double>.meanOrNull (skipNA : Boolean = skipNA_default): Double? = asSequence().meanOrNull (skipNA)
139139
140140@JvmName(" floatMean" )
141- internal fun Iterable<Float>.mean (skipNA : Boolean = skipNA_default): Double = asSequence().mean (skipNA)
141+ internal fun Iterable<Float>.meanOrNull (skipNA : Boolean = skipNA_default): Double? = asSequence().meanOrNull (skipNA)
142142
143143@JvmName(" bigDecimalMean" )
144- internal fun Iterable<BigDecimal>.mean (): BigDecimal ? = asSequence().mean ()
144+ internal fun Iterable<BigDecimal>.meanOrNull (): BigDecimal ? = asSequence().meanOrNull ()
145145
146146@JvmName(" bigIntegerMean" )
147- internal fun Iterable<BigInteger>.mean (): BigDecimal ? = asSequence().mean ()
147+ internal fun Iterable<BigInteger>.meanOrNull (): BigDecimal ? = asSequence().meanOrNull ()
148148
149149@JvmName(" intMean" )
150- internal fun Iterable<Int>.mean (): Double =
150+ internal fun Iterable<Int>.meanOrNull (): Double? =
151151 if (this is Collection ) {
152- if (size > 0 ) sumOf { it.toDouble() } / size else Double . NaN
152+ if (size > 0 ) sumOf { it.toDouble() } / size else null
153153 } else {
154154 var count = 0
155155 val sum = sumOf {
156156 count++
157157 it.toDouble()
158158 }
159- if (count > 0 ) sum / count else Double . NaN
159+ if (count > 0 ) sum / count else null
160160 }
161161
162162@JvmName(" shortMean" )
163- internal fun Iterable<Short>.mean (): Double =
163+ internal fun Iterable<Short>.meanOrNull (): Double? =
164164 if (this is Collection ) {
165- if (size > 0 ) sumOf { it.toDouble() } / size else Double . NaN
165+ if (size > 0 ) sumOf { it.toDouble() } / size else null
166166 } else {
167167 var count = 0
168168 val sum = sumOf {
169169 count++
170170 it.toDouble()
171171 }
172- if (count > 0 ) sum / count else Double . NaN
172+ if (count > 0 ) sum / count else null
173173 }
174174
175175@JvmName(" byteMean" )
176- internal fun Iterable<Byte>.mean (): Double =
176+ internal fun Iterable<Byte>.meanOrNull (): Double? =
177177 if (this is Collection ) {
178- if (size > 0 ) sumOf { it.toDouble() } / size else Double . NaN
178+ if (size > 0 ) sumOf { it.toDouble() } / size else null
179179 } else {
180180 var count = 0
181181 val sum = sumOf {
182182 count++
183183 it.toDouble()
184184 }
185- if (count > 0 ) sum / count else Double . NaN
185+ if (count > 0 ) sum / count else null
186186 }
187187
188188@JvmName(" longMean" )
189- internal fun Iterable<Long>.mean (): Double =
189+ internal fun Iterable<Long>.meanOrNull (): Double? =
190190 if (this is Collection ) {
191- if (size > 0 ) sumOf { it.toDouble() } / size else Double . NaN
191+ if (size > 0 ) sumOf { it.toDouble() } / size else null
192192 } else {
193193 var count = 0
194194 val sum = sumOf {
195195 count++
196196 it.toDouble()
197197 }
198- if (count > 0 ) sum / count else Double . NaN
198+ if (count > 0 ) sum / count else null
199199 }
0 commit comments