Skip to content

Commit e76f826

Browse files
committed
Move List<List<T>>.toDataFrame from io to api with deprecation
1 parent f3c62ce commit e76f826

File tree

6 files changed

+630
-52
lines changed

6 files changed

+630
-52
lines changed

core/api/core.api

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4462,7 +4462,9 @@ public final class org/jetbrains/kotlinx/dataframe/api/TakeKt {
44624462
}
44634463

44644464
public final class org/jetbrains/kotlinx/dataframe/api/ToDataFrameKt {
4465+
public static final fun toDataFrame (Ljava/util/List;Ljava/util/List;Z)Lorg/jetbrains/kotlinx/dataframe/DataFrame;
44654466
public static final fun toDataFrame (Ljava/util/Map;)Lorg/jetbrains/kotlinx/dataframe/DataFrame;
4467+
public static synthetic fun toDataFrame$default (Ljava/util/List;Ljava/util/List;ZILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame;
44664468
public static final fun toDataFrameAnyColumn (Ljava/lang/Iterable;)Lorg/jetbrains/kotlinx/dataframe/DataFrame;
44674469
public static final fun toDataFrameColumnPathAnyNullable (Ljava/lang/Iterable;)Lorg/jetbrains/kotlinx/dataframe/DataFrame;
44684470
public static final fun toDataFrameColumnPathAnyNullable (Ljava/util/Map;)Lorg/jetbrains/kotlinx/dataframe/DataFrame;
@@ -6099,8 +6101,8 @@ public final class org/jetbrains/kotlinx/dataframe/io/CommonKt {
60996101
public static final fun isURL (Ljava/lang/String;)Z
61006102
public static final fun isUrl (Ljava/lang/String;)Z
61016103
public static final fun skippingBomCharacters (Ljava/io/InputStream;)Ljava/io/InputStream;
6102-
public static final fun toDataFrame (Ljava/util/List;Ljava/util/List;Z)Lorg/jetbrains/kotlinx/dataframe/DataFrame;
6103-
public static synthetic fun toDataFrame$default (Ljava/util/List;Ljava/util/List;ZILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame;
6104+
public static final fun toDataFrame (Ljava/util/List;Z)Lorg/jetbrains/kotlinx/dataframe/DataFrame;
6105+
public static synthetic fun toDataFrame$default (Ljava/util/List;ZILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame;
61046106
public static final fun urlAsFile (Ljava/net/URL;)Ljava/io/File;
61056107
}
61066108

core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/toDataFrame.kt

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,3 +256,49 @@ public fun Map<ColumnPath, Iterable<Any?>>.toDataFrame(): AnyFrame =
256256
}.toDataFrameFromPairs<Unit>()
257257

258258
// endregion
259+
260+
/**
261+
* Converts a list of lists into a [DataFrame].
262+
*
263+
* By default, treats lists as row values. If [header] is not provided, the first inner list becomes a header (column names), and the remaining lists are treated as data.
264+
*
265+
* With [containsColumns] = `true`, interprets each inner list as a column.
266+
* If [header] is not provided, the first element will be used as the column name, and the remaining elements as values.
267+
*
268+
* @param T The type of elements contained in the nested lists.
269+
* @param containsColumns If `true`, treats each nested list as a column.
270+
* Otherwise, each nested list is a row.
271+
* Defaults to `false`.
272+
* @param header overrides extraction of column names from lists - all values are treated as data instead.
273+
* @return A [DataFrame] containing the data from the nested list structure.
274+
* Returns an empty [DataFrame] if the input is empty or invalid.
275+
*/
276+
@Refine
277+
@Interpretable("ValuesListsToDataFrame")
278+
public fun <T> List<List<T>>.toDataFrame(header: List<String>?, containsColumns: Boolean = false): AnyFrame =
279+
when {
280+
containsColumns -> {
281+
mapIndexedNotNull { index, list ->
282+
if (list.isEmpty()) return@mapIndexedNotNull null
283+
val name = header?.get(index) ?: list[0].toString()
284+
val values = if (header == null) list.drop(1) else list
285+
createColumnGuessingType(name, values)
286+
}.toDataFrame()
287+
}
288+
289+
isEmpty() -> DataFrame.Empty
290+
291+
else -> {
292+
val data = if (header == null) drop(1) else this
293+
(header ?: get(0).map { it.toString() }).mapIndexed { colIndex, name ->
294+
val values = data.map { row ->
295+
if (row.size <= colIndex) {
296+
null
297+
} else {
298+
row[colIndex]
299+
}
300+
}
301+
createColumnGuessingType(name, values)
302+
}.toDataFrame()
303+
}
304+
}

core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/common.kt

Lines changed: 7 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,11 @@ package org.jetbrains.kotlinx.dataframe.io
33
import org.apache.commons.io.input.BOMInputStream
44
import org.jetbrains.kotlinx.dataframe.AnyFrame
55
import org.jetbrains.kotlinx.dataframe.DataFrame
6-
import org.jetbrains.kotlinx.dataframe.annotations.Interpretable
7-
import org.jetbrains.kotlinx.dataframe.annotations.Refine
86
import org.jetbrains.kotlinx.dataframe.api.toDataFrame
9-
import org.jetbrains.kotlinx.dataframe.impl.columns.createColumnGuessingType
107
import org.jetbrains.kotlinx.dataframe.util.IS_URL
118
import org.jetbrains.kotlinx.dataframe.util.IS_URL_IMPORT
129
import org.jetbrains.kotlinx.dataframe.util.IS_URL_REPLACE
10+
import org.jetbrains.kotlinx.dataframe.util.LISTS_TO_DATAFRAME_MIGRATION
1311
import java.io.File
1412
import java.io.InputStream
1513
import java.net.HttpURLConnection
@@ -47,51 +45,12 @@ public fun catchHttpResponse(url: URL, body: (InputStream) -> AnyFrame): AnyFram
4745
}
4846
}
4947

50-
/**
51-
* Converts a list of lists into a [DataFrame].
52-
*
53-
* By default, treats lists as rows. If [header] is not provided, the first inner list becomes a header (column names), and the remaining lists are treated as data.
54-
*
55-
* With [containsColumns] = `true`, interprets each inner list as a column.
56-
* If [header] is not provided, the first element will be used as the column name, and the remaining elements as values.
57-
*
58-
* @param T The type of elements contained in the nested lists.
59-
* @param containsColumns If `true`, treats each nested list as a column.
60-
* Otherwise, each nested list is a row.
61-
* Defaults to `false`.
62-
* @param header overrides extraction of column names from lists - all values are treated as data instead.
63-
* @return A [DataFrame] containing the data from the nested list structure.
64-
* Returns an empty [DataFrame] if the input is empty or invalid.
65-
*/
66-
@Refine
67-
@Interpretable("ValuesListsToDataFrame")
68-
public fun <T> List<List<T>>.toDataFrame(header: List<String>? = null, containsColumns: Boolean = false): AnyFrame =
69-
when {
70-
containsColumns -> {
71-
mapIndexedNotNull { index, list ->
72-
if (list.isEmpty()) return@mapIndexedNotNull null
73-
val name = header?.get(index) ?: list[0].toString()
74-
val values = if (header == null) list.drop(1) else list
75-
createColumnGuessingType(name, values)
76-
}.toDataFrame()
77-
}
78-
79-
isEmpty() -> DataFrame.Empty
80-
81-
else -> {
82-
val data = if (header == null) drop(1) else this
83-
(header ?: get(0).map { it.toString() }).mapIndexed { colIndex, name ->
84-
val values = data.map { row ->
85-
if (row.size <= colIndex) {
86-
null
87-
} else {
88-
row[colIndex]
89-
}
90-
}
91-
createColumnGuessingType(name, values)
92-
}.toDataFrame()
93-
}
94-
}
48+
@Deprecated(
49+
LISTS_TO_DATAFRAME_MIGRATION,
50+
ReplaceWith("this.toDataFrame(header = null, containsColumns)", "org.jetbrains.kotlinx.dataframe.api.toDataFrame"),
51+
)
52+
public fun <T> List<List<T>>.toDataFrame(containsColumns: Boolean = false): AnyFrame =
53+
toDataFrame(header = null, containsColumns)
9554

9655
@Deprecated(
9756
message = IS_URL,

core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,9 @@ internal const val GET_ROWS_RANGE_REPLACE = "df().getRows(indices)"
257257
internal const val GET_ROW_OR_NULL_REPLACE = "df().getRowOrNull(index)"
258258
internal const val COPY_REPLACE = "columns().toDataFrame().cast()"
259259

260+
internal const val LISTS_TO_DATAFRAME_MIGRATION =
261+
"Function moved from io to api package, and a new `header` parameter is introduced. $MESSAGE_1_1"
262+
260263
// endregion
261264

262265
// region keep across releases

core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/toDataFrame.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import org.jetbrains.kotlinx.dataframe.DataRow
1616
import org.jetbrains.kotlinx.dataframe.annotations.ColumnName
1717
import org.jetbrains.kotlinx.dataframe.annotations.DataSchema
1818
import org.jetbrains.kotlinx.dataframe.columns.ColumnKind
19-
import org.jetbrains.kotlinx.dataframe.io.toDataFrame
2019
import org.jetbrains.kotlinx.dataframe.kind
2120
import org.jetbrains.kotlinx.dataframe.type
2221
import org.junit.Test
@@ -784,7 +783,7 @@ class CreateDataFrameTests {
784783
val df = lines
785784
.chunked(7)
786785
.map { it.dropLast(1) }
787-
.toDataFrame(containsColumns = true)
786+
.toDataFrame(header = null, containsColumns = true)
788787
df.columnNames() shouldBe header
789788
df.columnTypes() shouldBe List(4) { typeOf<String>() }
790789
df["col 0"].values() shouldBe listOf("data0 0", "data0 1", "data0 2", "data0 3", "data0 4")

0 commit comments

Comments
 (0)