X को स्केल में (के रूप में) परिभाषित दो स्तंभों के डेटाफ्रेम होने दें

case class Pair(X: String, Y: String)

val x = sqlContext.createDataFrame(Seq(
   Pair("u1", "1"), 
   Pair("u2", "wrong value"), 
   Pair("u3", "5"), 
   Pair("u4", "2")
))

मैं इस डेटाफ्रेम को साफ करना चाहता हूं जैसे कि दूसरे कॉलम का प्रत्येक मान है

  1. यदि संभव हो तो int को कास्ट किया
  2. अशक्त, ना या किसी भी प्रतीक से प्रतिस्थापित करें जिसका अर्थ है "गायब मूल्य" (NaN नहीं है, जो अलग है)

मैं udf फ़ंक्शन का उपयोग करने के बारे में सोच रहा था

val stringToInt = udf[Int, String](x => try {
     x.toInt
   } catch {
     case e: Exception => null
   })

x.withColumn("Y", stringToInt(x("Y")))

... लेकिन अशक्त एक स्ट्रिंग नहीं है, और संकलक इसे मना कर देता है। कृपया, इसके लिए क्या उपाय है? जब तक मैं अपने डेटाफ़्रेम को साफ कर सकता हूं, तब तक एक पूरी तरह से अलग दृष्टिकोण भी ठीक होगा

2
Boris 18 नवम्बर 2015, 17:30

2 जवाब

सबसे बढ़िया उत्तर

वास्तव में इस विशेष मामले में यूडीएफ की कोई आवश्यकता नहीं है। इसके बजाय आप सुरक्षित रूप से Column.cast विधि का उपयोग कर सकते हैं:

import org.apache.spark.sql.types.IntegerType
val clean = x.withColumn("Y", $"Y".cast(IntegerType)) // or .cast("integer")

clean.where($"Y".isNotNull).show
// +---+---+
// |  X|  Y|
// +---+---+
// | u1|  1|
// | u3|  5|
// | u4|  2|
// +---+---+

clean.where($"Y".isNull).show
// +---+----+
// |  X|   Y|
// +---+----+
// | u2|null|
// +---+----+
4
zero323 18 नवम्बर 2015, 15:51

null का उपयोग करने के बजाय, Option[Int] का उपयोग करें:

val pairs = Seq(
   Pair("u1", "1"), 
   Pair("u2", "wrong value"), 
   Pair("u3", "5"), 
   Pair("u4", "2")
)

def toInt(s: String): Option[Int] = try { Some(s.toInt) } catch { case NumberFormatException => None }

val stringToInt = udf[Int, Option[Int]](toInt _)

तब आप कर सकते हैं

val x = sqlContext.createDataFrame(pairs)
x.withColumn("Y", stringToInt(x("Y")))
2
Daenyth 18 नवम्बर 2015, 15:51