मैं स्पार्क एसक्यूएल के डेटाफ़्रेम में कॉलम प्रकार कैसे बदल सकता हूं?


152

मान लीजिए मैं कुछ ऐसा कर रहा हूं:

val df = sqlContext.load("com.databricks.spark.csv", Map("path" -> "cars.csv", "header" -> "true"))
df.printSchema()

root
 |-- year: string (nullable = true)
 |-- make: string (nullable = true)
 |-- model: string (nullable = true)
 |-- comment: string (nullable = true)
 |-- blank: string (nullable = true)

df.show()
year make  model comment              blank
2012 Tesla S     No comment
1997 Ford  E350  Go get one now th...

लेकिन मैं वास्तव में yearजैसा चाहता था Int(और शायद कुछ अन्य स्तंभों को बदलना)।

सबसे अच्छा मैं साथ आ सकता था

df.withColumn("year2", 'year.cast("Int")).select('year2 as 'year, 'make, 'model, 'comment, 'blank)
org.apache.spark.sql.DataFrame = [year: int, make: string, model: string, comment: string, blank: string]

जो थोड़ा दृढ़ हो।

मैं आर से आ रहा हूं, और मैं लिखने में सक्षम हूं, जैसे

df2 <- df %>%
   mutate(year = year %>% as.integer,
          make = make %>% toupper)

मुझे कुछ याद आ रहा है, क्योंकि स्पार्क / स्काला में ऐसा करने का एक बेहतर तरीका होना चाहिए ...


मुझे इस तरह से पसंद है। spark.sql ("SELECT STRING (NULLIF (कॉलम, '')) को कॉलम_स्ट्रिंग के रूप में")
Eric Bellet

जवाबों:


141

संपादित करें: नवीनतम संस्करण

चिंगारी 2.x के बाद से आप उपयोग कर सकते हैं .withColumn। डॉक्स यहां देखें:

https://spark.apache.org/docs/latest/api/scala/index.html#org.apache.spark.sql.Dataset@withColumn(colName:String,col:org.apache.spark.sql.Column) : org.apache.spark.sql.DataFrame

सबसे पुराना उत्तर

स्पार्क संस्करण 1.4 के बाद से आप कॉलम पर डेटा टाइप के साथ कास्ट विधि लागू कर सकते हैं:

import org.apache.spark.sql.types.IntegerType
val df2 = df.withColumn("yearTmp", df.year.cast(IntegerType))
    .drop("year")
    .withColumnRenamed("yearTmp", "year")

यदि आप sql अभिव्यक्ति का उपयोग कर रहे हैं तो आप भी कर सकते हैं:

val df2 = df.selectExpr("cast(year as int) year", 
                        "make", 
                        "model", 
                        "comment", 
                        "blank")

अधिक जानकारी के लिए डॉक्स देखें: http://spark.apache.org/docs/1.6.0/api/scala/#org.apache.spark.sql.DataFrame


4
आपने ड्रॉप के बाद कॉलेयम का उपयोग क्यों किया? मूल कॉलम नाम के साथ केवल कॉलम का उपयोग करना आसान नहीं है?
अमीबा स्पूगनोसा

@AmebaSpugnosa मुझे लगता है कि जब तक मैं इसका इस्तेमाल करता था तब तक स्पार्क दुर्घटनाग्रस्त हो जाता था अगर इसमें स्तंभ नाम दोहराए जाते। जब आप उन्हें नहीं बनाते हैं, लेकिन जब आप उनका उपयोग करते हैं।
msemelman

5
नाम बदलने के बाद कॉलम को छोड़ने की आवश्यकता नहीं है। आप एक पंक्ति में कर सकते हैंdf.withColumn("ctr", temp("ctr").cast(DecimalType(decimalPrecision, decimalScale)))
ruhong

1
क्या इस मामले में एक कॉलम को फिर से लिखने के लिए एक पूरी नई डेटाफ़्रेम कॉपी बनाई गई है? क्या मैं कुछ भूल रहा हूँ? या शायद पर्दे के पीछे कुछ अनुकूलन है?
user1814008 23

5
द्वारा जा रहे हैं डॉक्स का Spark 2.x, df.withColumn(..)कर सकते हैं जोड़ने या बदलने के आधार पर एक स्तंभ colNameतर्क
Y2K-शुभम

89

[संपादित: मार्च २०१६: वोटों के लिए धन्यवाद! हालांकि वास्तव में, यह सबसे अच्छा जवाब नहीं है, मुझे लगता है कि समाधान के आधार पर withColumn, withColumnRenamedऔरcast msemelman, मार्टिन Senne और दूसरों द्वारा आगे रखा सरल और क्लीनर हैं]।

मुझे लगता है कि आपका दृष्टिकोण ठीक है, याद रखें कि स्पार्क DataFrameपंक्तियों का एक (अपरिवर्तनीय) आरडीडी है, इसलिए हम कभी भी एक कॉलम की जगह नहीं ले रहे हैं , बस DataFrameहर बार एक नया स्कीमा बना रहे हैं।

मान लें कि आपके पास निम्नलिखित स्कीमा के साथ एक मूल df है:

scala> df.printSchema
root
 |-- Year: string (nullable = true)
 |-- Month: string (nullable = true)
 |-- DayofMonth: string (nullable = true)
 |-- DayOfWeek: string (nullable = true)
 |-- DepDelay: string (nullable = true)
 |-- Distance: string (nullable = true)
 |-- CRSDepTime: string (nullable = true)

और कुछ यूडीएफ को एक या कई स्तंभों पर परिभाषित किया गया है:

import org.apache.spark.sql.functions._

val toInt    = udf[Int, String]( _.toInt)
val toDouble = udf[Double, String]( _.toDouble)
val toHour   = udf((t: String) => "%04d".format(t.toInt).take(2).toInt ) 
val days_since_nearest_holidays = udf( 
  (year:String, month:String, dayOfMonth:String) => year.toInt + 27 + month.toInt-12
 )

स्तंभ प्रकार बदलना या किसी अन्य से नया DataFrame बनाना इस तरह लिखा जा सकता है:

val featureDf = df
.withColumn("departureDelay", toDouble(df("DepDelay")))
.withColumn("departureHour",  toHour(df("CRSDepTime")))
.withColumn("dayOfWeek",      toInt(df("DayOfWeek")))              
.withColumn("dayOfMonth",     toInt(df("DayofMonth")))              
.withColumn("month",          toInt(df("Month")))              
.withColumn("distance",       toDouble(df("Distance")))              
.withColumn("nearestHoliday", days_since_nearest_holidays(
              df("Year"), df("Month"), df("DayofMonth"))
            )              
.select("departureDelay", "departureHour", "dayOfWeek", "dayOfMonth", 
        "month", "distance", "nearestHoliday")            

कौन सी पैदावार:

scala> df.printSchema
root
 |-- departureDelay: double (nullable = true)
 |-- departureHour: integer (nullable = true)
 |-- dayOfWeek: integer (nullable = true)
 |-- dayOfMonth: integer (nullable = true)
 |-- month: integer (nullable = true)
 |-- distance: double (nullable = true)
 |-- nearestHoliday: integer (nullable = true)

यह आपके अपने समाधान के बहुत करीब है। बस, एस प्रकार परिवर्तन और अन्य परिवर्तनों को अलग-अलग रखने से udf valकोड अधिक पठनीय और पुन: प्रयोज्य हो जाता है।


26
यह न तो सुरक्षित है और न ही कुशल। सुरक्षित नहीं है क्योंकि एकल NULLया विकृत प्रविष्टि पूरी नौकरी को ध्वस्त कर देगी। कुशल नहीं है क्योंकि UDF उत्प्रेरक के लिए पारदर्शी नहीं हैं। जटिल ऑपरेशन के लिए यूडीएफ का उपयोग करना ठीक है, लेकिन बुनियादी प्रकार की कास्टिंग के लिए इनका उपयोग करने का कोई कारण नहीं है। इसके कारण हमारे पास castविधि है ( मार्टिन सेने का उत्तर देखें )। उत्प्रेरक के लिए चीजों को पारदर्शी बनाने के लिए अधिक काम करने की आवश्यकता होती है लेकिन बुनियादी सुरक्षा सिर्फ काम करने Tryऔर Optionकाम करने की बात है ।
शून्य 323

मैंने "05-APR-2015" के लिए स्ट्रिंग को परिवर्तित करने से संबंधित कुछ भी नहीं देखा
21

3
क्या आपके withColumn()अनुभाग को एक सामान्य से कम करने का एक तरीका है जो सभी स्तंभों के माध्यम से पुनरावृत्त करता है?
बर्न

शुक्रिया जीरो 323, इसे पढ़ने के बाद मुझे लगा कि udf समाधान यहाँ क्यों क्रैश होता है। कुछ टिप्पणियां SO :) के कुछ जवाबों से बेहतर हैं
साइमन डेर्मियर

क्या कोई ऐसा तरीका है जिससे हम भ्रष्ट पंक्ति को जान सकते हैं, मतलब रिकॉर्ड्स जो कि कास्टिंग के दौरान गलत डेटा प्रकारों के कॉलम हैं। जैसा कि कास्ट फ़ंक्शन उन फ़ील्ड्स को अशक्त बनाता है
Etisha

65

चूंकि castऑपरेशन स्पार्क के लिए उपलब्ध है Column(और जैसा कि मैं व्यक्तिगत udfरूप Svendसे इस बिंदु पर @ द्वारा प्रस्तावित के रूप में अनुकूल नहीं हूं ), कैसे:

df.select( df("year").cast(IntegerType).as("year"), ... )

अनुरोधित प्रकार पर जाने के लिए? एक साफ साइड इफेक्ट के रूप में, उस अर्थ में कास्टेबल / "कन्वर्टेबल" नहीं हैं null

यदि आपको एक सहायक विधि के रूप में इसकी आवश्यकता है , तो उपयोग करें:

object DFHelper{
  def castColumnTo( df: DataFrame, cn: String, tpe: DataType ) : DataFrame = {
    df.withColumn( cn, df(cn).cast(tpe) )
  }
}

जो इस तरह प्रयोग किया जाता है:

import DFHelper._
val df2 = castColumnTo( df, "year", IntegerType )

2
क्या आप मुझे सलाह दे सकते हैं कि कैसे आगे बढ़ना है, अगर मुझे कॉलम का एक पूरा गुच्छा बनाने और नाम बदलने की आवश्यकता है (मेरे पास 50 कॉलम हैं, और स्कैला के लिए काफी नया है, तो निश्चित रूप से यह नहीं है कि बड़े पैमाने पर दोहराव पैदा किए बिना उससे संपर्क करने का सबसे अच्छा तरीका क्या है)? कुछ स्तंभों को स्ट्रिंग रहना चाहिए, कुछ को फ़्लोट में डाला जाना चाहिए।
दिमित्री स्मिरनोव

कॉलम में "25-APR-2016" और "20160302" के लिए एक स्ट्रिंग को दिनांक में कैसे परिवर्तित किया जाए
dbspace

@DmitrySmirnov क्या आपको कभी जवाब मिला? मेरे पास भी वही प्रश्न है। ;)
इवान ज़मीर

@EvanZamir दुर्भाग्य से, मैं अन्य चरणों में डेटा के रूप में डेटा का उपयोग करने में सक्षम होने के लिए संचालन का एक प्रकार का कार्य कर रहा था। मुझे आश्चर्य है कि अगर यह इन दिनों आसान हो गया :)
दिमित्री स्मिरनोव

60

सबसे पहले , यदि आप कास्ट प्रकार चाहते हैं, तो यह:

import org.apache.spark.sql
df.withColumn("year", $"year".cast(sql.types.IntegerType))

समान कॉलम नाम के साथ, कॉलम को नए के साथ बदल दिया जाएगा। आपको चरणों को जोड़ने और हटाने की आवश्यकता नहीं है।

दूसरा , स्काला बनाम आर के बारे में ।
यह वह कोड है जो आरआई के समान हो सकता है:

val df2 = df.select(
   df.columns.map {
     case year @ "year" => df(year).cast(IntegerType).as(year)
     case make @ "make" => functions.upper(df(make)).as(make)
     case other         => df(other)
   }: _*
)

हालांकि कोड की लंबाई R की तुलना में थोड़ी लंबी है। इसका भाषा की वाचालता से कोई लेना-देना नहीं है। आर में mutateआर डेटाफ्रेम के लिए एक विशेष कार्य है, जबकि स्काला में आप आसानी से अपनी अभिव्यंजक शक्ति के लिए धन्यवाद कर सकते हैं।
शब्द में, यह विशिष्ट समाधानों से बचता है, क्योंकि भाषा डिज़ाइन आपके लिए अपनी डोमेन भाषा को जल्दी और आसानी से बनाने के लिए पर्याप्त है।


साइड नोट: df.columnsआश्चर्यजनक रूप से Array[String]इसके बजाय Array[Column], शायद वे चाहते हैं कि यह पायथन पांडा के डेटाफ्रेम जैसा दिखे।


1
क्या आप कृपया pyspark के लिए समकक्ष दे सकते हैं?
हरित विश्वकर्मा

मुझे अपने "आयु" क्षेत्र के लिए "परिभाषा की अवैध शुरुआत" .withColumn ("आयु", $ "आयु" .cast (sql.types.DoubleType)) मिल रही है। कोई उपाय?
ब्लूडोल्फिन

क्या आपके पास .cache () डेटा फ़्रेम है यदि हम प्रदर्शन के कारण कई कॉलमों पर ये रूपांतरण कर रहे हैं, या इसकी आवश्यकता नहीं है क्योंकि स्पार्क उनका अनुकूलन करता है?
स्किजगिनी

आयात हो सकता है import org.apache.spark.sql.types._और फिर sql.types.IntegerTypeसिर्फ के बजाय IntegerType
nessa.gp

17

आप selectExprइसे थोड़ा साफ करने के लिए उपयोग कर सकते हैं :

df.selectExpr("cast(year as int) as year", "upper(make) as make",
    "model", "comment", "blank")

14

String से Integer तक DataFrame के डेटाटाइप को संशोधित करने के लिए जावा कोड

df.withColumn("col_name", df.col("col_name").cast(DataTypes.IntegerType))

यह केवल मौजूदा (स्ट्रिंग डेटाटाइप) को इंटेगर को कास्ट करेगा।


1
इसमें कोई नहीं DataTypesहै sql.types! यह है DataType। इसके अलावा, एक बस आयात IntegerTypeऔर डाली जा सकती है ।
एहसान एम। करमानी

@ EhsanM.Kermani वास्तव में DatyaTypes.IntegerType एक कानूनी संदर्भ है।
22

1
@Cupitor DataTypes.IntegerTypeमें हुआ करता था DeveloperAPI मोड और यह v.2.1.0 में स्थिर
एहसान एम Kermani

यह सबसे अच्छा उपाय है!
साइमन डेर्मियर

8

वर्ष को स्ट्रिंग से इंट में बदलने के लिए, आप निम्न विकल्प को csv रीडर में जोड़ सकते हैं: "inferSchema" -> "सही", देखें DataBricks प्रलेखन


5
यह अच्छी तरह से काम करता है लेकिन पकड़ यह है कि पाठक को आपकी फ़ाइल का दूसरा पास करना होगा
beefyhalo

@beefyhalo बिल्कुल हाजिर है, क्या उसके आसपास कोई रास्ता है?
आयुष

6

तो यह वास्तव में तभी काम करता है जब आपके पास sqlserver जैसे jdbc ड्राइवर को सहेजने के मुद्दे हों, लेकिन यह उन त्रुटियों के लिए वास्तव में मददगार है जिन्हें आप सिंटैक्स और प्रकारों के साथ चलाएंगे।

import org.apache.spark.sql.jdbc.{JdbcDialects, JdbcType, JdbcDialect}
import org.apache.spark.sql.jdbc.JdbcType
val SQLServerDialect = new JdbcDialect {
  override def canHandle(url: String): Boolean = url.startsWith("jdbc:jtds:sqlserver") || url.contains("sqlserver")

  override def getJDBCType(dt: DataType): Option[JdbcType] = dt match {
    case StringType => Some(JdbcType("VARCHAR(5000)", java.sql.Types.VARCHAR))
    case BooleanType => Some(JdbcType("BIT(1)", java.sql.Types.BIT))
    case IntegerType => Some(JdbcType("INTEGER", java.sql.Types.INTEGER))
    case LongType => Some(JdbcType("BIGINT", java.sql.Types.BIGINT))
    case DoubleType => Some(JdbcType("DOUBLE PRECISION", java.sql.Types.DOUBLE))
    case FloatType => Some(JdbcType("REAL", java.sql.Types.REAL))
    case ShortType => Some(JdbcType("INTEGER", java.sql.Types.INTEGER))
    case ByteType => Some(JdbcType("INTEGER", java.sql.Types.INTEGER))
    case BinaryType => Some(JdbcType("BINARY", java.sql.Types.BINARY))
    case TimestampType => Some(JdbcType("DATE", java.sql.Types.DATE))
    case DateType => Some(JdbcType("DATE", java.sql.Types.DATE))
    //      case DecimalType.Fixed(precision, scale) => Some(JdbcType("NUMBER(" + precision + "," + scale + ")", java.sql.Types.NUMERIC))
    case t: DecimalType => Some(JdbcType(s"DECIMAL(${t.precision},${t.scale})", java.sql.Types.DECIMAL))
    case _ => throw new IllegalArgumentException(s"Don't know how to save ${dt.json} to JDBC")
  }
}

JdbcDialects.registerDialect(SQLServerDialect)

क्या आप मुझे जावा में समान कोड लागू करने में मदद कर सकते हैं? और डेटाफ़्रेम में customJdbcDialect कैसे रजिस्टर करें
abhijitcaps

अच्छा मैंने वर्टिका के साथ भी यही किया, लेकिन चिंगारी 2.1 से। JDbcUtil आपको केवल विशिष्ट विशिष्ट डेटा को लागू करने की आवश्यकता है। dialect.getJDBCType (dt) .orElse (getCommonJDBCType (dt))। getOrElse (new IllegalArgumentException को फेंक दें (s "$ {dt.simpleString}" के लिए DDBC प्रकार प्राप्त नहीं कर सकते हैं))
Rodman

6

पाँच मूल्यों और परिवर्तित युक्त एक सरल डाटासेट उत्पन्न intकरने के लिए stringटाइप करें:

val df = spark.range(5).select( col("id").cast("string") )

6

मुझे लगता है कि यह मेरे लिए बहुत अधिक पठनीय है।

import org.apache.spark.sql.types._
df.withColumn("year", df("year").cast(IntegerType))

यह आपके वर्ष के कॉलम को IntegerTypeकिसी भी अस्थायी कॉलम बनाने और उन कॉलमों को छोड़ने के साथ बदल देगा । यदि आप किसी अन्य डेटाटाइप में कनवर्ट करना चाहते हैं, तो आप org.apache.spark.sql.typesपैकेज के अंदर के प्रकारों की जांच कर सकते हैं ।


5

कास्ट, FYI करें, स्पार्क 1.4.1 में कास्ट विधि का उपयोग करने का सुझाव देने वाले उत्तर टूट गए हैं।

उदाहरण के लिए, एक स्ट्रिंग स्तंभ के साथ एक डेटाफ्रेम जिसका मूल्य "8182175552014127960" है, जब बिगिन को कास्ट किया जाता है, तो इसका मूल्य "8182175552014128100" होता है

    df.show
+-------------------+
|                  a|
+-------------------+
|8182175552014127960|
+-------------------+

    df.selectExpr("cast(a as bigint) a").show
+-------------------+
|                  a|
+-------------------+
|8182175552014128100|
+-------------------+

इस बग को खोजने से पहले हमें बहुत सारे मुद्दों का सामना करना पड़ा क्योंकि हमारे पास उत्पादन में बड़े स्तंभ थे।


4
psst, अपनी चिंगारी को अपग्रेड करें
msemelman

2
@msemelman छोटे बग के लिए उत्पादन में स्पार्क के एक नए संस्करण में अपग्रेड करना हास्यास्पद है।
sauraI3h

क्या हम हमेशा छोटे कीड़े के लिए सब कुछ अपग्रेड नहीं करते हैं? :)
कैसरसोल


4

स्पार्क Sql 2.4.0 का उपयोग करके आप ऐसा कर सकते हैं:

spark.sql("SELECT STRING(NULLIF(column,'')) as column_string")

3

आप नीचे दिए गए कोड का उपयोग कर सकते हैं।

df.withColumn("year", df("year").cast(IntegerType))

जो साल कॉलम को IntegerTypeकॉलम में बदल देगा ।


2

यह विधि पुराने कॉलम को छोड़ देगी और समान मान और नए डेटाटाइप के साथ नए कॉलम बनाएगी। जब डेटाफ़्रेम बनाया गया था, तो मेरा मूल डेटाटिप्स: -

root
 |-- id: integer (nullable = true)
 |-- flag1: string (nullable = true)
 |-- flag2: string (nullable = true)
 |-- name: string (nullable = true)
 |-- flag3: string (nullable = true)

इसके बाद मैंने डेटाटाइप को बदलने के लिए निम्न कोड चलाया: -

df=df.withColumnRenamed(<old column name>,<dummy column>) // This was done for both flag1 and flag3
df=df.withColumn(<old column name>,df.col(<dummy column>).cast(<datatype>)).drop(<dummy column>)

इसके बाद मेरा रिजल्ट निकला: -

root
 |-- id: integer (nullable = true)
 |-- flag2: string (nullable = true)
 |-- name: string (nullable = true)
 |-- flag1: boolean (nullable = true)
 |-- flag3: boolean (nullable = true)

क्या आप कृपया यहां अपना समाधान प्रदान कर सकते हैं।
अजय खराड़े

1

स्पार्क एसक्यूएल में कास्ट का उपयोग करके एक स्तंभ का डेटा प्रकार बदल सकता है। तालिका का नाम तालिका है और इसमें दो कॉलम केवल column1 और column2 हैं और column1 डेटा प्रकार को बदलना है। ex-spark.sql ("select cast (column1 as double) column1NewName, column2 from table") डबल के स्थान पर अपना डेटा टाइप लिखें।


1

यदि आपको उनके नाम से दिए गए दर्जनों स्तंभों का नाम बदलना है, तो निम्न उदाहरण @dnlbrky का दृष्टिकोण लेता है और एक साथ कई स्तंभों पर लागू होता है:

df.selectExpr(df.columns.map(cn => {
    if (Set("speed", "weight", "height").contains(cn)) s"cast($cn as double) as $cn"
    else if (Set("isActive", "hasDevice").contains(cn)) s"cast($cn as boolean) as $cn"
    else cn
}):_*)

अनचाही कॉलम को अपरिवर्तित रखा गया है। सभी कॉलम अपने मूल क्रम में रहते हैं।


1

इतने सारे उत्तर और बहुत अधिक स्पष्टीकरण नहीं

निम्नलिखित सिंटैक्स स्पार्क 2.4 के साथ डेटाब्रिक नोटबुक का उपयोग करके काम करता है

from pyspark.sql.functions import *
df = df.withColumn("COL_NAME", to_date(BLDFm["LOAD_DATE"], "MM-dd-yyyy"))

ध्यान दें कि आपको अपने पास प्रवेश प्रारूप निर्दिष्ट करना होगा (मेरे मामले में "MM-dd-yyyy") और आयात अनिवार्य है क्योंकि to_date एक स्पार्क sql फ़ंक्शन है

इस सिंटैक्स को भी आज़माया लेकिन एक उचित कलाकार के बजाय नल मिला:

df = df.withColumn("COL_NAME", df["COL_NAME"].cast("Date"))

(ध्यान दें कि मुझे इसके लिए वाक्यविन्यास सही होने के लिए कोष्ठक और उद्धरण का उपयोग करना था)


PS: मुझे यह स्वीकार करना होगा कि यह वाक्यविन्यास जंगल की तरह है, कई संभव तरीके से प्रवेश बिंदु हैं, और आधिकारिक एपीआई संदर्भों में उचित उदाहरणों की कमी है।


1
सिंटेक्स जंगल। हाँ। यह अभी स्पार्क की दुनिया है।
coner.xyz

1

एक अन्य समाधान इस प्रकार है:

1) "बांझपन" को झूठे के रूप में रखें

2) पंक्ति में 'मैप' फ़ंक्शन चलाने के दौरान, आप 'asString' (row.getString ...) पढ़ सकते हैं

//Read CSV and create dataset
Dataset<Row> enginesDataSet = sparkSession
            .read()
            .format("com.databricks.spark.csv")
            .option("header", "true")
            .option("inferSchema","false")
            .load(args[0]);

JavaRDD<Box> vertices = enginesDataSet
            .select("BOX","BOX_CD")
            .toJavaRDD()
            .map(new Function<Row, Box>() {
                @Override
                public Box call(Row row) throws Exception {
                    return new Box((String)row.getString(0),(String)row.get(1));
                }
            });


0
    val fact_df = df.select($"data"(30) as "TopicTypeId", $"data"(31) as "TopicId",$"data"(21).cast(FloatType).as( "Data_Value_Std_Err")).rdd
    //Schema to be applied to the table
    val fact_schema = (new StructType).add("TopicTypeId", StringType).add("TopicId", StringType).add("Data_Value_Std_Err", FloatType)

    val fact_table = sqlContext.createDataFrame(fact_df, fact_schema).dropDuplicates()

0

दूसरा रास्ता:

// Generate a simple dataset containing five values and convert int to string type

val df = spark.range(5).select( col("id").cast("string")).withColumnRenamed("id","value")

0

यदि आप व्यक्तिगत कॉलम नामों को निर्दिष्ट किए बिना एक विशिष्ट प्रकार के कई कॉलमों को दूसरे में बदलना चाहते हैं

/* Get names of all columns that you want to change type. 
In this example I want to change all columns of type Array to String*/
    val arrColsNames = originalDataFrame.schema.fields.filter(f => f.dataType.isInstanceOf[ArrayType]).map(_.name)

//iterate columns you want to change type and cast to the required type
val updatedDataFrame = arrColsNames.foldLeft(originalDataFrame){(tempDF, colName) => tempDF.withColumn(colName, tempDF.col(colName).cast(DataTypes.StringType))}

//display

updatedDataFrame.show(truncate = false)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.