@@ -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
11
14
import org.jetbrains.kotlinx.dataframe.api.cast
12
15
import org.jetbrains.kotlinx.dataframe.api.indices
13
16
import org.jetbrains.kotlinx.dataframe.api.isEmpty
14
17
import org.jetbrains.kotlinx.dataframe.api.name
15
18
import org.jetbrains.kotlinx.dataframe.api.replace
19
+ import org.jetbrains.kotlinx.dataframe.api.rows
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,45 @@ 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
+ val src = it.asColumnGroup()
57
+ val updatedColumn = expression(src, src).asColumnGroup(src.name())
58
+ if (filter == null ) {
59
+ // If there is no filter, we simply replace the selected column groups with the result of the expression
60
+ updatedColumn
61
+ } else {
62
+ // If there is a filter, we collect the indices of the rows that are inside the filter
63
+ val collector = createDataCollector<DataRow <C >>(it.size, it.type)
64
+ val indices = buildList {
65
+ df.indices().forEach { rowIndex ->
66
+ val row = AddDataRowImpl (rowIndex, df, collector.values)
67
+ val currentValue = row[src]
68
+
69
+ if (filter.invoke(row, currentValue)) {
70
+ this + = rowIndex
71
+ collector.add(currentValue)
72
+ }
73
+ }
74
+ }
75
+
76
+ // Then we only replace the original rows with the updated rows that are inside the filter
77
+ src.rows().map {
78
+ val index = indices.indexOf(it.index)
79
+ if (index == - 1 ) it else updatedColumn[index]
80
+ }.toColumn(src.name)
81
+ }
82
+ }
83
+
43
84
internal fun <T , C > DataColumn<C>.updateImpl (
44
85
df : DataFrame <T >,
45
86
filter : RowValueFilter <T , C >? ,
46
- expression : (AddDataRow <T >, DataColumn <C >, C ) -> C ?
87
+ expression : (AddDataRow <T >, DataColumn <C >, C ) -> C ? ,
47
88
): DataColumn <C > {
48
89
val collector = createDataCollector<C >(size, type)
49
90
val src = this
@@ -75,6 +116,7 @@ internal fun <T> DataColumn<T>.updateWith(values: List<T>): DataColumn<T> = when
75
116
val groups = (values as List <AnyFrame >)
76
117
DataColumn .createFrameColumn(name, groups) as DataColumn <T >
77
118
}
119
+
78
120
is ColumnGroup <* > -> {
79
121
this .columns().mapIndexed { colIndex, col ->
80
122
val newValues = values.map {
@@ -88,6 +130,7 @@ internal fun <T> DataColumn<T>.updateWith(values: List<T>): DataColumn<T> = when
88
130
col.updateWith(newValues)
89
131
}.toDataFrame().let { DataColumn .createColumnGroup(name, it) } as DataColumn <T >
90
132
}
133
+
91
134
else -> {
92
135
var nulls = false
93
136
val kclass = type.jvmErasure
0 commit comments