Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

df1Row[df2Column] == df1Row[df2Column.name] #445

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
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
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,79 @@ internal open class DataRowImpl<T>(private val index: Int, private val df: DataF

override operator fun <R> get(column: ColumnReference<R>): R {
ColumnAccessTracker.registerColumnAccess(column.name())
return column.getValue(this)

val fromColumnByRow = column.getValue(this)

val fromDfByName = df
.let {
try {
it.getColumnOrNull(column.name())
} catch (e: IllegalStateException) {
return fromColumnByRow
}
}
.let { it ?: return fromColumnByRow }
.let {
try {
it[index]
} catch (e: IndexOutOfBoundsException) {
return fromColumnByRow
}
}
.let {
try {
it as R
} catch (e: ClassCastException) {
return fromColumnByRow
}
}

return when {

// Issue #442: df1Row[df2Column] should be df1Row[df2Column.name], not df2Column[df1Row(.index)]
// so, give fromDfByName priority if it's not the same as fromColumnByRow
fromDfByName != fromColumnByRow -> fromDfByName

else -> fromColumnByRow
}
}

override fun <R> getValueOrNull(column: ColumnReference<R>): R? {
ColumnAccessTracker.registerColumnAccess(column.name())
return column.getValueOrNull(this)

val fromColumnByRow = column.getValueOrNull(this)

val fromDfByName = df
.let {
try {
it.getColumnOrNull(column.name())
} catch (e: IllegalStateException) {
return fromColumnByRow
}
}
.let { it ?: return fromColumnByRow }
.let {
try {
it[index]
} catch (e: IndexOutOfBoundsException) {
return fromColumnByRow
}
}.let {
try {
it as R?
} catch (e: ClassCastException) {
return fromColumnByRow
}
}

return when {

// Issue #442: df1Row[df2Column] should be df1Row[df2Column.name], not df2Column[df1Row(.index)]
// so, give fromDfByName priority if it's not the same as fromColumnByRow
fromDfByName != fromColumnByRow -> fromDfByName

else -> fromColumnByRow
}
}

override fun index() = index
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ internal fun AnyFrame.toListImpl(type: KType): List<Any> {

return rows().map { row ->
val parameters = convertedColumns.map {
row[it]
it[row]
}.toTypedArray()
constructor.call(*parameters)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ package org.jetbrains.kotlinx.dataframe.api
import io.kotest.assertions.throwables.shouldThrow
import io.kotest.assertions.throwables.shouldThrowAny
import io.kotest.matchers.shouldBe
import io.kotest.matchers.shouldNotBe
import io.kotest.matchers.string.shouldContain
import org.jetbrains.kotlinx.dataframe.DataFrame
import org.jetbrains.kotlinx.dataframe.alsoDebug
import org.jetbrains.kotlinx.dataframe.annotations.DataSchema
import org.junit.Test
import java.lang.ClassCastException
import java.lang.IllegalArgumentException

class GetTests {

Expand All @@ -30,6 +30,7 @@ class GetTests {
fun `get value from row`() {
val a by column<Int>()
val c by column<Int>()

data class A(val a: Int, val b: Int, val c: Int)

val df = dataFrameOf("a", "b")(1, 2)
Expand Down Expand Up @@ -89,4 +90,46 @@ class GetTests {
}
throwable.message shouldContain "Cannot cast null value of a ValueColumn to"
}

@Test
fun `select data column with same name as in df`() {
val df = dataFrameOf("a")(1, 2, 3)

val aColumnAccessor = column<String>("a")
df.select { aColumnAccessor } shouldBe df

val directColumn = columnOf(4, 5, 6) named "a"
// TODO issue #457:
// df.select { directColumn } shouldBe dataFrameOf(directColumn)

val otherDfColumn = dataFrameOf("a")(4, 5, 6)["a"]
df.select { otherDfColumn } shouldBe dataFrameOf(otherDfColumn)
}

@Test
fun `Get column from a data row`() {
val df1 = dataFrameOf("a")(1, 2, 3)
val a by column<String>()
val aPath = pathOf("a")

val df2 = dataFrameOf("a")(4, 5, 6)

df1.rows().forEach { df1Row ->
val df2Col = df2["a"]

df1Row["a"] shouldBe df1[df1Row.index()][0]

df1Row[a] shouldBe df1[df1Row.index()][0]

df1Row[aPath] shouldBe df1[df1Row.index()][0]

df1Row[df2Col.name()] shouldBe df1[df1Row.index()][0]

df1Row[df2Col] shouldNotBe df2Col[df1Row] // old

df1Row[df2Col] shouldBe df1Row[df2Col.name()] // new

df1Row[df2Col] shouldBe df1[df1Row.index()][0]
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,79 @@ internal open class DataRowImpl<T>(private val index: Int, private val df: DataF

override operator fun <R> get(column: ColumnReference<R>): R {
ColumnAccessTracker.registerColumnAccess(column.name())
return column.getValue(this)

val fromColumnByRow = column.getValue(this)

val fromDfByName = df
.let {
try {
it.getColumnOrNull(column.name())
} catch (e: IllegalStateException) {
return fromColumnByRow
}
}
.let { it ?: return fromColumnByRow }
.let {
try {
it[index]
} catch (e: IndexOutOfBoundsException) {
return fromColumnByRow
}
}
.let {
try {
it as R
} catch (e: ClassCastException) {
return fromColumnByRow
}
}

return when {

// Issue #442: df1Row[df2Column] should be df1Row[df2Column.name], not df2Column[df1Row(.index)]
// so, give fromDfByName priority if it's not the same as fromColumnByRow
fromDfByName != fromColumnByRow -> fromDfByName

else -> fromColumnByRow
}
}

override fun <R> getValueOrNull(column: ColumnReference<R>): R? {
ColumnAccessTracker.registerColumnAccess(column.name())
return column.getValueOrNull(this)

val fromColumnByRow = column.getValueOrNull(this)

val fromDfByName = df
.let {
try {
it.getColumnOrNull(column.name())
} catch (e: IllegalStateException) {
return fromColumnByRow
}
}
.let { it ?: return fromColumnByRow }
.let {
try {
it[index]
} catch (e: IndexOutOfBoundsException) {
return fromColumnByRow
}
}.let {
try {
it as R?
} catch (e: ClassCastException) {
return fromColumnByRow
}
}

return when {

// Issue #442: df1Row[df2Column] should be df1Row[df2Column.name], not df2Column[df1Row(.index)]
// so, give fromDfByName priority if it's not the same as fromColumnByRow
fromDfByName != fromColumnByRow -> fromDfByName

else -> fromColumnByRow
}
}

override fun index() = index
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ internal fun AnyFrame.toListImpl(type: KType): List<Any> {

return rows().map { row ->
val parameters = convertedColumns.map {
row[it]
it[row]
}.toTypedArray()
constructor.call(*parameters)
}
Expand Down
47 changes: 45 additions & 2 deletions core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/get.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ package org.jetbrains.kotlinx.dataframe.api
import io.kotest.assertions.throwables.shouldThrow
import io.kotest.assertions.throwables.shouldThrowAny
import io.kotest.matchers.shouldBe
import io.kotest.matchers.shouldNotBe
import io.kotest.matchers.string.shouldContain
import org.jetbrains.kotlinx.dataframe.DataFrame
import org.jetbrains.kotlinx.dataframe.alsoDebug
import org.jetbrains.kotlinx.dataframe.annotations.DataSchema
import org.junit.Test
import java.lang.ClassCastException
import java.lang.IllegalArgumentException

class GetTests {

Expand All @@ -30,6 +30,7 @@ class GetTests {
fun `get value from row`() {
val a by column<Int>()
val c by column<Int>()

data class A(val a: Int, val b: Int, val c: Int)

val df = dataFrameOf("a", "b")(1, 2)
Expand Down Expand Up @@ -89,4 +90,46 @@ class GetTests {
}
throwable.message shouldContain "Cannot cast null value of a ValueColumn to"
}

@Test
fun `select data column with same name as in df`() {
val df = dataFrameOf("a")(1, 2, 3)

val aColumnAccessor = column<String>("a")
df.select { aColumnAccessor } shouldBe df

val directColumn = columnOf(4, 5, 6) named "a"
// TODO issue #457:
// df.select { directColumn } shouldBe dataFrameOf(directColumn)

val otherDfColumn = dataFrameOf("a")(4, 5, 6)["a"]
df.select { otherDfColumn } shouldBe dataFrameOf(otherDfColumn)
}

@Test
fun `Get column from a data row`() {
val df1 = dataFrameOf("a")(1, 2, 3)
val a by column<String>()
val aPath = pathOf("a")

val df2 = dataFrameOf("a")(4, 5, 6)

df1.rows().forEach { df1Row ->
val df2Col = df2["a"]

df1Row["a"] shouldBe df1[df1Row.index()][0]

df1Row[a] shouldBe df1[df1Row.index()][0]

df1Row[aPath] shouldBe df1[df1Row.index()][0]

df1Row[df2Col.name()] shouldBe df1[df1Row.index()][0]

df1Row[df2Col] shouldNotBe df2Col[df1Row] // old

df1Row[df2Col] shouldBe df1Row[df2Col.name()] // new

df1Row[df2Col] shouldBe df1[df1Row.index()][0]
}
}
}