Skip to content

Commit 46a8564

Browse files
committed
add public API to create dataframes with empty columns by a schema
It's needed in Kandy to create GroupBy with empty groups that can still be aggregated, as per added test
1 parent 6f89eb9 commit 46a8564

File tree

4 files changed

+52
-0
lines changed
  • core

4 files changed

+52
-0
lines changed

core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/DataFrame.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ import org.jetbrains.kotlinx.dataframe.impl.DataFrameSize
1616
import org.jetbrains.kotlinx.dataframe.impl.getColumnsImpl
1717
import org.jetbrains.kotlinx.dataframe.impl.headPlusArray
1818
import org.jetbrains.kotlinx.dataframe.impl.headPlusIterable
19+
import org.jetbrains.kotlinx.dataframe.impl.schema.createEmptyDataFrame
1920
import org.jetbrains.kotlinx.dataframe.impl.schema.createEmptyDataFrameOf
21+
import org.jetbrains.kotlinx.dataframe.schema.DataFrameSchema
2022
import kotlin.reflect.KType
2123

2224
/**
@@ -33,6 +35,8 @@ public interface DataFrame<out T> : Aggregatable<T>, ColumnsContainer<T> {
3335
public fun empty(nrow: Int = 0): AnyFrame = if (nrow == 0) Empty else DataFrameImpl<Unit>(emptyList(), nrow)
3436

3537
public inline fun <reified T> emptyOf(): DataFrame<T> = createEmptyDataFrameOf(T::class).cast()
38+
39+
public fun empty(schema: DataFrameSchema): AnyFrame = schema.createEmptyDataFrame()
3640
}
3741

3842
// region columns

core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/DataFrameTests.kt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2383,4 +2383,26 @@ class DataFrameTests : BaseTest() {
23832383
val newName by column<String>()
23842384
typed.select { name into newName and age }.columnNames() shouldBe listOf("newName", "age")
23852385
}
2386+
2387+
@Test
2388+
fun `api for creating GroupBy with empty groups which can be aggregated using statistics`() {
2389+
val df1 = dataFrameOf("a", "b")(1, "c")
2390+
val df2 = DataFrame.empty()
2391+
val groupBy = dataFrameOf(columnOf("group1", "group2") named "group", columnOf(df1, df2)).asGroupBy()
2392+
2393+
shouldThrow<IllegalStateException> {
2394+
groupBy.aggregate {
2395+
sum("a")
2396+
}
2397+
}
2398+
2399+
val groupBy1 = groupBy
2400+
.updateGroups { if (it.isEmpty()) DataFrame.empty(groupBy.groups.schema.value) else it }
2401+
2402+
val res = groupBy1.aggregate {
2403+
sum("a")
2404+
}
2405+
2406+
res["aggregated"].values() shouldBe listOf(1, 0)
2407+
}
23862408
}

core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/DataFrame.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ import org.jetbrains.kotlinx.dataframe.impl.DataFrameSize
1616
import org.jetbrains.kotlinx.dataframe.impl.getColumnsImpl
1717
import org.jetbrains.kotlinx.dataframe.impl.headPlusArray
1818
import org.jetbrains.kotlinx.dataframe.impl.headPlusIterable
19+
import org.jetbrains.kotlinx.dataframe.impl.schema.createEmptyDataFrame
1920
import org.jetbrains.kotlinx.dataframe.impl.schema.createEmptyDataFrameOf
21+
import org.jetbrains.kotlinx.dataframe.schema.DataFrameSchema
2022
import kotlin.reflect.KType
2123

2224
/**
@@ -33,6 +35,8 @@ public interface DataFrame<out T> : Aggregatable<T>, ColumnsContainer<T> {
3335
public fun empty(nrow: Int = 0): AnyFrame = if (nrow == 0) Empty else DataFrameImpl<Unit>(emptyList(), nrow)
3436

3537
public inline fun <reified T> emptyOf(): DataFrame<T> = createEmptyDataFrameOf(T::class).cast()
38+
39+
public fun empty(schema: DataFrameSchema): AnyFrame = schema.createEmptyDataFrame()
3640
}
3741

3842
// region columns

core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/DataFrameTests.kt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2383,4 +2383,26 @@ class DataFrameTests : BaseTest() {
23832383
val newName by column<String>()
23842384
typed.select { name into newName and age }.columnNames() shouldBe listOf("newName", "age")
23852385
}
2386+
2387+
@Test
2388+
fun `api for creating GroupBy with empty groups which can be aggregated using statistics`() {
2389+
val df1 = dataFrameOf("a", "b")(1, "c")
2390+
val df2 = DataFrame.empty()
2391+
val groupBy = dataFrameOf(columnOf("group1", "group2") named "group", columnOf(df1, df2)).asGroupBy()
2392+
2393+
shouldThrow<IllegalStateException> {
2394+
groupBy.aggregate {
2395+
sum("a")
2396+
}
2397+
}
2398+
2399+
val groupBy1 = groupBy
2400+
.updateGroups { if (it.isEmpty()) DataFrame.empty(groupBy.groups.schema.value) else it }
2401+
2402+
val res = groupBy1.aggregate {
2403+
sum("a")
2404+
}
2405+
2406+
res["aggregated"].values() shouldBe listOf(1, 0)
2407+
}
23862408
}

0 commit comments

Comments
 (0)