This is an automated email from the ASF dual-hosted git repository.

zhengruifeng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark.git


The following commit(s) were added to refs/heads/master by this push:
     new 7a6c598a1b2c [SPARK-58535][ML] Create StringIndexer lookup maps during 
transformation
7a6c598a1b2c is described below

commit 7a6c598a1b2c14e60de25318c96d27f9cbfa4c80
Author: Ruifeng Zheng <[email protected]>
AuthorDate: Tue Aug 4 14:56:00 2026 +0800

    [SPARK-58535][ML] Create StringIndexer lookup maps during transformation
    
    ### What changes were proposed in this pull request?
    
    This patch creates the StringIndexerModel label-to-index lookup maps inside 
`transform` and passes them to invalid-value filtering. The maps are no longer 
retained as derived model state.
    
    ### Why are the changes needed?
    
    The lookup maps are only needed to transform input data. Creating them 
during transformation avoids retaining them on models that are fit or loaded 
but never transformed.
    
    ### Does this PR introduce _any_ user-facing change?
    
    No.
    
    ### How was this patch tested?
    
    `build/sbt 'mllib/testOnly 
org.apache.spark.ml.feature.StringIndexerSuite'`\n\nAll 28 tests passed. No new 
test was added because this is an internal lifecycle refactor; the existing 
suite covers normal indexing and invalid-value handling.\n\n### Was this patch 
authored or co-authored using generative AI tooling?\n\nGenerated-by: Codex 
(GPT-5)
    
    Closes #57735 from zhengruifeng/lazy-string-indexer-labels-to-index.
    
    Authored-by: Ruifeng Zheng <[email protected]>
    Signed-off-by: Ruifeng Zheng <[email protected]>
---
 .../apache/spark/ml/feature/StringIndexer.scala    | 28 ++++++++++------------
 1 file changed, 13 insertions(+), 15 deletions(-)

diff --git 
a/mllib/src/main/scala/org/apache/spark/ml/feature/StringIndexer.scala 
b/mllib/src/main/scala/org/apache/spark/ml/feature/StringIndexer.scala
index 8bb07d3f0260..c0f7e312dcbb 100644
--- a/mllib/src/main/scala/org/apache/spark/ml/feature/StringIndexer.scala
+++ b/mllib/src/main/scala/org/apache/spark/ml/feature/StringIndexer.scala
@@ -316,20 +316,8 @@ class StringIndexerModel (
     labelsArray(0)
   }
 
-  // Prepares the maps for string values to corresponding index values.
-  private val labelsToIndexArray: Array[OpenHashMap[String, Double]] = {
-    for (labels <- labelsArray) yield {
-      val n = labels.length
-      val map = new OpenHashMap[String, Double](n)
-      labels.zipWithIndex.foreach { case (label, idx) =>
-        map.update(label, idx)
-      }
-      map
-    }
-  }
-
   private[spark] override def estimatedSize: Long =
-    estimateMatadataSize + SizeEstimator.estimate((labelsArray, 
labelsToIndexArray))
+    estimateMatadataSize + SizeEstimator.estimate(labelsArray)
 
   /** @group setParam */
   @Since("1.6.0")
@@ -353,7 +341,10 @@ class StringIndexerModel (
 
   // This filters out any null values and also the input labels which are not 
in
   // the dataset used for fitting.
-  private def filterInvalidData(dataset: Dataset[_], inputColNames: 
Seq[String]): Dataset[_] = {
+  private def filterInvalidData(
+      dataset: Dataset[_],
+      inputColNames: Seq[String],
+      labelsToIndexArray: Array[OpenHashMap[String, Double]]): Dataset[_] = {
     val conditions: Seq[Column] = inputColNames.indices.map { i =>
       val inputColName = inputColNames(i)
       val labelToIndex = labelsToIndexArray(i)
@@ -401,11 +392,18 @@ class StringIndexerModel (
     transformSchema(dataset.schema, logging = true)
 
     val (inputColNames, outputColNames) = getInOutCols()
+    val labelsToIndexArray = labelsArray.map { labels =>
+      val map = new OpenHashMap[String, Double](labels.length)
+      labels.zipWithIndex.foreach { case (label, idx) =>
+        map.update(label, idx)
+      }
+      map
+    }
     val outputColumns = new Array[Column](outputColNames.length)
 
     // Skips invalid rows if `handleInvalid` is set to 
`StringIndexer.SKIP_INVALID`.
     val filteredDataset = if (getHandleInvalid == StringIndexer.SKIP_INVALID) {
-      filterInvalidData(dataset, inputColNames.toImmutableArraySeq)
+      filterInvalidData(dataset, inputColNames.toImmutableArraySeq, 
labelsToIndexArray)
     } else {
       dataset
     }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to