Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions core/api/core.api
Original file line number Diff line number Diff line change
Expand Up @@ -5304,12 +5304,10 @@ public abstract interface class org/jetbrains/kotlinx/dataframe/columns/ValueCol
public synthetic fun distinct ()Lorg/jetbrains/kotlinx/dataframe/DataColumn;
public synthetic fun distinct ()Lorg/jetbrains/kotlinx/dataframe/columns/BaseColumn;
public abstract fun distinct ()Lorg/jetbrains/kotlinx/dataframe/columns/ValueColumn;
public synthetic fun get (Ljava/lang/Iterable;)Lorg/jetbrains/kotlinx/dataframe/DataColumn;
public abstract fun get (Ljava/lang/Iterable;)Lorg/jetbrains/kotlinx/dataframe/DataColumn;
public synthetic fun get (Ljava/lang/Iterable;)Lorg/jetbrains/kotlinx/dataframe/columns/BaseColumn;
public abstract fun get (Ljava/lang/Iterable;)Lorg/jetbrains/kotlinx/dataframe/columns/ValueColumn;
public synthetic fun get (Lkotlin/ranges/IntRange;)Lorg/jetbrains/kotlinx/dataframe/DataColumn;
public abstract fun get (Lkotlin/ranges/IntRange;)Lorg/jetbrains/kotlinx/dataframe/DataColumn;
public synthetic fun get (Lkotlin/ranges/IntRange;)Lorg/jetbrains/kotlinx/dataframe/columns/BaseColumn;
public abstract fun get (Lkotlin/ranges/IntRange;)Lorg/jetbrains/kotlinx/dataframe/columns/ValueColumn;
public synthetic fun getValue (Ljava/lang/Object;Lkotlin/reflect/KProperty;)Lorg/jetbrains/kotlinx/dataframe/DataColumn;
public synthetic fun getValue (Ljava/lang/Object;Lkotlin/reflect/KProperty;)Lorg/jetbrains/kotlinx/dataframe/columns/BaseColumn;
public synthetic fun getValue (Ljava/lang/Object;Lkotlin/reflect/KProperty;)Lorg/jetbrains/kotlinx/dataframe/columns/ColumnReference;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import org.jetbrains.kotlinx.dataframe.DataFrame
import org.jetbrains.kotlinx.dataframe.columns.ColumnGroup
import org.jetbrains.kotlinx.dataframe.columns.FrameColumn
import org.jetbrains.kotlinx.dataframe.columns.ValueColumn
import org.jetbrains.kotlinx.dataframe.impl.columns.asValueColumn
import org.jetbrains.kotlinx.dataframe.indices

public fun <T> DataFrame<T>.reverse(): DataFrame<T> = get(indices.reversed())
Expand All @@ -15,4 +16,4 @@ public fun <T> ColumnGroup<T>.reverse(): ColumnGroup<T> = get(indices.reversed()

public fun <T> FrameColumn<T>.reverse(): FrameColumn<T> = get(indices.reversed())

public fun <T> ValueColumn<T>.reverse(): ValueColumn<T> = get(indices.reversed())
public fun <T> ValueColumn<T>.reverse(): ValueColumn<T> = get(indices.reversed()).asValueColumn()
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ public interface ValueColumn<out T> : DataColumn<T> {

override fun distinct(): ValueColumn<T>

override fun get(indices: Iterable<Int>): ValueColumn<T>
override fun get(indices: Iterable<Int>): DataColumn<T>

override fun rename(newName: String): ValueColumn<T>

override operator fun getValue(thisRef: Any?, property: KProperty<*>): ValueColumn<T> =
super.getValue(thisRef, property) as ValueColumn<T>

public override operator fun get(range: IntRange): ValueColumn<T>
public override operator fun get(range: IntRange): DataColumn<T>

/**
* Changes column [type][BaseColumn.type].
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.jetbrains.kotlinx.dataframe.impl.columns
import org.jetbrains.kotlinx.dataframe.AnyFrame
import org.jetbrains.kotlinx.dataframe.AnyRow
import org.jetbrains.kotlinx.dataframe.DataColumn
import org.jetbrains.kotlinx.dataframe.api.cast
import org.jetbrains.kotlinx.dataframe.columns.ColumnGroup
import org.jetbrains.kotlinx.dataframe.columns.ColumnResolutionContext
import org.jetbrains.kotlinx.dataframe.columns.ValueColumn
Expand Down Expand Up @@ -78,12 +79,17 @@ internal open class ValueColumnImpl<T>(

override fun addParent(parent: ColumnGroup<*>): DataColumn<T> = ValueColumnWithParent(parent, this)

override fun createWithValues(values: List<T>, hasNulls: Boolean?): ValueColumn<T> {
override fun createWithValues(values: List<T>, hasNulls: Boolean?): DataColumn<T> {
val nulls = hasNulls ?: values.any { it == null }

// If this value column was of type `AnyFrame?` and all nulls are filtered out, return a frame column instead
if (!nulls && type.isSubtypeOf(typeOf<AnyFrame?>())) {
return DataColumn.createFrameColumn(name, values as List<AnyFrame>).cast()
}
return DataColumn.createValueColumn(name, values, type.withNullability(nulls))
}

override fun get(indices: Iterable<Int>): ValueColumn<T> {
override fun get(indices: Iterable<Int>): DataColumn<T> {
var nullable = false
val newValues = indices.map {
val value = values[it]
Expand All @@ -96,7 +102,7 @@ internal open class ValueColumnImpl<T>(
override fun get(columnName: String) =
throw UnsupportedOperationException("Can not get nested column '$columnName' from ValueColumn '$name'")

override operator fun get(range: IntRange): ValueColumn<T> = super<DataColumnImpl>.get(range) as ValueColumn<T>
override operator fun get(range: IntRange): DataColumn<T> = super<DataColumnImpl>.get(range) as DataColumn<T>

override fun defaultValue() = defaultValue

Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,29 @@
package org.jetbrains.kotlinx.dataframe.columns

import io.kotest.assertions.throwables.shouldNotThrowAny
import io.kotest.assertions.throwables.shouldThrow
import io.kotest.matchers.shouldBe
import org.jetbrains.kotlinx.dataframe.AnyFrame
import org.jetbrains.kotlinx.dataframe.DataColumn
import org.jetbrains.kotlinx.dataframe.DataFrame
import org.jetbrains.kotlinx.dataframe.api.dataFrameOf
import org.jetbrains.kotlinx.dataframe.api.dropNulls
import org.jetbrains.kotlinx.dataframe.api.emptyDataFrame
import org.jetbrains.kotlinx.dataframe.api.take
import org.jetbrains.kotlinx.dataframe.api.toColumn
import org.jetbrains.kotlinx.dataframe.api.toDataFrame
import org.jetbrains.kotlinx.dataframe.api.update
import org.jetbrains.kotlinx.dataframe.api.where
import org.jetbrains.kotlinx.dataframe.api.with
import org.jetbrains.kotlinx.dataframe.core.BuildConfig
import org.jetbrains.kotlinx.dataframe.samples.api.TestBase.Person
import org.jetbrains.kotlinx.dataframe.testSets.person.BaseTest
import org.junit.Test
import java.net.URI
import kotlin.reflect.full.isSubtypeOf
import kotlin.reflect.typeOf

class DataColumns {
class DataColumns : BaseTest() {
@Test
fun `create column with platform type from Api`() {
val df1 = listOf(1, 2, 3).toDataFrame {
Expand Down Expand Up @@ -61,4 +73,51 @@ class DataColumns {
)
}
}

// Tests for issue #1926
val nullableDfValueColumnDf = dataFrameOf(
DataColumn.createValueColumn("col", listOf(df, null)),
)

@Test
fun `checking nullableDfValueColumnDf creation`() {
nullableDfValueColumnDf["col"].let {
it.kind() shouldBe ColumnKind.Value
it.type().isSubtypeOf(typeOf<DataFrame<*>?>()) shouldBe true
}
}

@Test
fun `test removing nulls update from nullable DF ValueCol should turn into FrameCol`() {
val updatedDf = nullableDfValueColumnDf
.update("col").where { it == null }.with { emptyDataFrame<Person>() }
updatedDf["col"].let {
it.kind() shouldBe ColumnKind.Frame
it.type().isSubtypeOf(typeOf<DataFrame<*>>()) shouldBe true
}
}

@Test
fun `test dropNulls from nullable DF ValueCol should turn into FrameCol`() {
shouldNotThrowAny {
nullableDfValueColumnDf["col"].dropNulls()
}
val droppedDf = nullableDfValueColumnDf.dropNulls("col")
droppedDf["col"].let {
it.kind() shouldBe ColumnKind.Frame
it.type().isSubtypeOf(typeOf<DataFrame<*>>()) shouldBe true
}
}

@Test
fun `test take from nullable DF ValueCol should turn into FrameCol`() {
shouldNotThrowAny {
nullableDfValueColumnDf["col"].take(1)
}
val takenDf = nullableDfValueColumnDf.take(1)
takenDf["col"].let {
it.kind() shouldBe ColumnKind.Frame
it.type().isSubtypeOf(typeOf<DataFrame<*>>()) shouldBe true
}
}
}
Loading