Skip to content

Commit 6c1c027

Browse files
committed
Add cumSum function for DataColumn, DataFrame, and GroupBy
Introduces a cumSum operation to compute cumulative sums with options to skip null values. Documentation and overloads are added for DataColumn, DataFrame, and GroupBy, ensuring consistency across API components. This update enhances support for common data aggregation workflows.
1 parent 6bf0a3f commit 6c1c027

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/cumSum.kt

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ import org.jetbrains.kotlinx.dataframe.ColumnsSelector
55
import org.jetbrains.kotlinx.dataframe.DataColumn
66
import org.jetbrains.kotlinx.dataframe.DataFrame
77
import org.jetbrains.kotlinx.dataframe.annotations.AccessApiOverload
8+
import org.jetbrains.kotlinx.dataframe.api.Select.SelectSelectingOptions
89
import org.jetbrains.kotlinx.dataframe.columns.toColumnSet
10+
import org.jetbrains.kotlinx.dataframe.documentation.DocumentationUrls
11+
import org.jetbrains.kotlinx.dataframe.documentation.ExcludeFromSources
912
import org.jetbrains.kotlinx.dataframe.impl.nothingType
1013
import org.jetbrains.kotlinx.dataframe.impl.nullableNothingType
1114
import org.jetbrains.kotlinx.dataframe.math.cumSum
@@ -18,6 +21,36 @@ import kotlin.reflect.typeOf
1821

1922
// region DataColumn
2023

24+
/**
25+
* ## The CumSum Operation
26+
*
27+
* Computes the cumulative sum of the values in the {@get DATA_TYPE}.
28+
*
29+
* __NOTE:__ If the column contains nullable values and `skipNA` is set to `true`,
30+
* skips null values when computing the cumulative sum.
31+
* Otherwise, any null value encountered will propagate null values in the output from that point onward.
32+
*
33+
* {@get [CUMSUM_PARAM] @param [columns]
34+
* The names of the columns to apply cumSum operation.}
35+
*
36+
* @param [skipNA] Whether to skip null values (default: `true`).
37+
*
38+
* @return A new {@get DATA_TYPE} of the same type with the cumulative sum of the values.
39+
*
40+
* {@get [CUMSUM_PARAM] @see [Selecting Columns][SelectSelectingOptions].}
41+
* @see {@include [DocumentationUrls.CumSum]}
42+
*/
43+
@ExcludeFromSources
44+
@Suppress("ClassName")
45+
private interface CumSumDocs {
46+
interface CUMSUM_PARAM
47+
}
48+
49+
/**
50+
* {@include [CumSumDocs]}
51+
* {@set DATA_TYPE [DataColumn]}.
52+
* {@set [CumSumDocs.CUMSUM_PARAM]}
53+
*/
2154
public fun <T : Number?> DataColumn<T>.cumSum(skipNA: Boolean = defaultCumSumSkipNA): DataColumn<T> =
2255
when (type()) {
2356
typeOf<Double>() -> cast<Double>().cumSum(skipNA).cast()
@@ -79,25 +112,46 @@ private val supportedClasses = setOf(
79112

80113
// region DataFrame
81114

115+
/**
116+
* {@include [CumSumDocs]}
117+
* {@set DATA_TYPE [DataFrame]}.
118+
*/
82119
public fun <T, C> DataFrame<T>.cumSum(
83120
skipNA: Boolean = defaultCumSumSkipNA,
84121
columns: ColumnsSelector<T, C>,
85122
): DataFrame<T> =
86123
convert(columns).to { if (it.typeClass in supportedClasses) it.cast<Number?>().cumSum(skipNA) else it }
87124

125+
/**
126+
* {@include [CumSumDocs]}
127+
* {@set DATA_TYPE [DataFrame]}.
128+
*/
88129
public fun <T> DataFrame<T>.cumSum(vararg columns: String, skipNA: Boolean = defaultCumSumSkipNA): DataFrame<T> =
89130
cumSum(skipNA) { columns.toColumnSet() }
90131

132+
/**
133+
* {@include [CumSumDocs]}
134+
* {@set DATA_TYPE [DataFrame]}.
135+
*/
91136
@AccessApiOverload
92137
public fun <T> DataFrame<T>.cumSum(
93138
vararg columns: AnyColumnReference,
94139
skipNA: Boolean = defaultCumSumSkipNA,
95140
): DataFrame<T> = cumSum(skipNA) { columns.toColumnSet() }
96141

142+
/**
143+
* {@include [CumSumDocs]}
144+
* {@set DATA_TYPE [DataFrame]}.
145+
*/
97146
@AccessApiOverload
98147
public fun <T> DataFrame<T>.cumSum(vararg columns: KProperty<*>, skipNA: Boolean = defaultCumSumSkipNA): DataFrame<T> =
99148
cumSum(skipNA) { columns.toColumnSet() }
100149

150+
/**
151+
* {@include [CumSumDocs]}
152+
* {@set DATA_TYPE [DataFrame]}.
153+
* {@set [CumSumDocs.CUMSUM_PARAM]}
154+
*/
101155
public fun <T> DataFrame<T>.cumSum(skipNA: Boolean = defaultCumSumSkipNA): DataFrame<T> =
102156
cumSum(skipNA) {
103157
colsAtAnyDepth { !it.isColumnGroup() }
@@ -107,26 +161,47 @@ public fun <T> DataFrame<T>.cumSum(skipNA: Boolean = defaultCumSumSkipNA): DataF
107161

108162
// region GroupBy
109163

164+
/**
165+
* {@include [CumSumDocs]}
166+
* {@set DATA_TYPE [GroupBy]}.
167+
*/
110168
public fun <T, G, C> GroupBy<T, G>.cumSum(
111169
skipNA: Boolean = defaultCumSumSkipNA,
112170
columns: ColumnsSelector<G, C>,
113171
): GroupBy<T, G> = updateGroups { cumSum(skipNA, columns) }
114172

173+
/**
174+
* {@include [CumSumDocs]}
175+
* {@set DATA_TYPE [GroupBy]}.
176+
*/
115177
public fun <T, G> GroupBy<T, G>.cumSum(vararg columns: String, skipNA: Boolean = defaultCumSumSkipNA): GroupBy<T, G> =
116178
cumSum(skipNA) { columns.toColumnSet() }
117179

180+
/**
181+
* {@include [CumSumDocs]}
182+
* {@set DATA_TYPE [GroupBy]}.
183+
*/
118184
@AccessApiOverload
119185
public fun <T, G> GroupBy<T, G>.cumSum(
120186
vararg columns: AnyColumnReference,
121187
skipNA: Boolean = defaultCumSumSkipNA,
122188
): GroupBy<T, G> = cumSum(skipNA) { columns.toColumnSet() }
123189

190+
/**
191+
* {@include [CumSumDocs]}
192+
* {@set DATA_TYPE [GroupBy]}.
193+
*/
124194
@AccessApiOverload
125195
public fun <T, G> GroupBy<T, G>.cumSum(
126196
vararg columns: KProperty<*>,
127197
skipNA: Boolean = defaultCumSumSkipNA,
128198
): GroupBy<T, G> = cumSum(skipNA) { columns.toColumnSet() }
129199

200+
/**
201+
* {@include [CumSumDocs]}
202+
* {@set DATA_TYPE [GroupBy]}.
203+
* {@set [CumSumDocs.CUMSUM_PARAM]}
204+
*/
130205
public fun <T, G> GroupBy<T, G>.cumSum(skipNA: Boolean = defaultCumSumSkipNA): GroupBy<T, G> =
131206
cumSum(skipNA) {
132207
colsAtAnyDepth { !it.isColumnGroup() }

core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/DocumentationUrls.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,7 @@ internal interface DocumentationUrls {
8080

8181
/** <a href="{@include [Url]}/distinct.html">See `distinct` on the documentation website.</a> */
8282
interface Distinct
83+
84+
/** <a href="{@include [Url]}/cumsum.html">See `cumSum` on the documentation website.</a> */
85+
interface CumSum
8386
}

0 commit comments

Comments
 (0)