@@ -4,22 +4,28 @@ import org.jetbrains.kotlinx.dataframe.AnyFrame
4
4
import org.jetbrains.kotlinx.dataframe.AnyRow
5
5
import org.jetbrains.kotlinx.dataframe.DataColumn
6
6
import org.jetbrains.kotlinx.dataframe.DataFrame
7
+ import org.jetbrains.kotlinx.dataframe.DataFrameExpression
8
+ import org.jetbrains.kotlinx.dataframe.DataRow
7
9
import org.jetbrains.kotlinx.dataframe.RowValueFilter
8
10
import org.jetbrains.kotlinx.dataframe.Selector
9
11
import org.jetbrains.kotlinx.dataframe.api.AddDataRow
10
12
import org.jetbrains.kotlinx.dataframe.api.Update
13
+ import org.jetbrains.kotlinx.dataframe.api.asColumnGroup
14
+ import org.jetbrains.kotlinx.dataframe.api.asDataFrame
11
15
import org.jetbrains.kotlinx.dataframe.api.cast
12
16
import org.jetbrains.kotlinx.dataframe.api.indices
13
17
import org.jetbrains.kotlinx.dataframe.api.isEmpty
14
18
import org.jetbrains.kotlinx.dataframe.api.name
15
19
import org.jetbrains.kotlinx.dataframe.api.replace
20
+ import org.jetbrains.kotlinx.dataframe.api.toColumn
16
21
import org.jetbrains.kotlinx.dataframe.api.toDataFrame
17
22
import org.jetbrains.kotlinx.dataframe.api.with
18
23
import org.jetbrains.kotlinx.dataframe.columns.ColumnGroup
19
24
import org.jetbrains.kotlinx.dataframe.columns.FrameColumn
20
25
import org.jetbrains.kotlinx.dataframe.columns.size
21
26
import org.jetbrains.kotlinx.dataframe.impl.columns.AddDataRowImpl
22
27
import org.jetbrains.kotlinx.dataframe.impl.createDataCollector
28
+ import org.jetbrains.kotlinx.dataframe.index
23
29
import org.jetbrains.kotlinx.dataframe.type
24
30
import kotlin.reflect.full.isSubclassOf
25
31
import kotlin.reflect.full.withNullability
@@ -40,10 +46,48 @@ internal fun <T, C> Update<T, C>.updateWithValuePerColumnImpl(selector: Selector
40
46
}
41
47
}
42
48
49
+ /* *
50
+ * Implementation for Update As Frame:
51
+ * Replaces selected column groups with the result of the expression only where the filter is true.
52
+ */
53
+ internal fun <T , C , R > Update <T , DataRow <C >>.asFrameImpl (expression : DataFrameExpression <C , DataFrame <R >>): DataFrame <T > =
54
+ if (df.isEmpty()) df
55
+ else df.replace(columns).with {
56
+ // First, we create an updated column group with the result of the expression
57
+ val srcColumnGroup = it.asColumnGroup()
58
+ val updatedColumnGroup = srcColumnGroup
59
+ .asDataFrame()
60
+ .let { expression(it, it) }
61
+ .asColumnGroup(srcColumnGroup.name())
62
+
63
+ if (filter == null ) {
64
+ // If there is no filter, we simply return the updated column group
65
+ updatedColumnGroup
66
+ } else {
67
+ // If there is a filter, then we replace the rows of the source column group with the updated column group
68
+ // only if they satisfy the filter
69
+ srcColumnGroup.replaceRowsIf(from = updatedColumnGroup) {
70
+ val srcRow = df[it.index]
71
+ val srcValue = srcRow[srcColumnGroup]
72
+
73
+ filter.invoke(srcRow, srcValue)
74
+ }
75
+ }
76
+ }
77
+
78
+ private fun <C , R > ColumnGroup<C>.replaceRowsIf (
79
+ from : ColumnGroup <R >,
80
+ condition : (DataRow <C >) -> Boolean = { true },
81
+ ): ColumnGroup <C > = values()
82
+ .map { if (condition(it)) from[it.index] else it }
83
+ .toColumn(name)
84
+ .asColumnGroup()
85
+ .cast()
86
+
43
87
internal fun <T , C > DataColumn<C>.updateImpl (
44
88
df : DataFrame <T >,
45
89
filter : RowValueFilter <T , C >? ,
46
- expression : (AddDataRow <T >, DataColumn <C >, C ) -> C ?
90
+ expression : (AddDataRow <T >, DataColumn <C >, C ) -> C ? ,
47
91
): DataColumn <C > {
48
92
val collector = createDataCollector<C >(size, type)
49
93
val src = this
@@ -75,6 +119,7 @@ internal fun <T> DataColumn<T>.updateWith(values: List<T>): DataColumn<T> = when
75
119
val groups = (values as List <AnyFrame >)
76
120
DataColumn .createFrameColumn(name, groups) as DataColumn <T >
77
121
}
122
+
78
123
is ColumnGroup <* > -> {
79
124
this .columns().mapIndexed { colIndex, col ->
80
125
val newValues = values.map {
@@ -88,6 +133,7 @@ internal fun <T> DataColumn<T>.updateWith(values: List<T>): DataColumn<T> = when
88
133
col.updateWith(newValues)
89
134
}.toDataFrame().let { DataColumn .createColumnGroup(name, it) } as DataColumn <T >
90
135
}
136
+
91
137
else -> {
92
138
var nulls = false
93
139
val kclass = type.jvmErasure
0 commit comments