আমি কীভাবে স্পার্ক এসকিউএল এর ডেটাফ্রেমে কলামের ধরণগুলি পরিবর্তন করতে পারি?


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 ( "নির্বাচন করুন STRING টি (NULLIF (কলাম, '')) column_string যেমন") মত
এরিক 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

পুরানো উত্তর

স্পার্ক সংস্করণ ১.৪ থেকে আপনি কলামে ডেটা টাইপ দিয়ে কাস্ট পদ্ধতি প্রয়োগ করতে পারেন:

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

আপনি যদি স্কয়ার এক্সপ্রেশন ব্যবহার করেন তবে আপনি এটি করতেও পারেন:

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
আপনি কেন কলামটি ড্রপ অনুসরণ করে ব্যবহার করলেন? মূল কলামের নাম সহ কেবলমাত্র কলামটিই ব্যবহার করা সহজ নয়?
আমেবা স্পুগনোসা

@ আমেবাস্পুগনোসা আমার মনে হয় আমি যখন এটি ব্যবহার করেছি তখন স্পার্ক ক্র্যাশ হয়ে গেছে যদি এর কলামের নামগুলি বারবার ব্যবহার করা হত। আপনি এগুলি তৈরি করার সময় নয়, আপনি যখন তাদের ব্যবহার করবেন।
msemelman

5
একটি নাম পরিবর্তন করে কলাম বাদ দেওয়ার দরকার নেই। আপনি এক লাইনে করতে পারেনdf.withColumn("ctr", temp("ctr").cast(DecimalType(decimalPrecision, decimalScale)))
রুহং

1
এক্ষেত্রে একটি কলাম কাস্ট করার জন্য একটি সম্পূর্ণ নতুন ডেটাফ্রেম অনুলিপি তৈরি করা হয়েছে? আমি কিছু অনুপস্থিত করছি? নাকি পর্দার আড়ালে কিছু অপ্টিমাইজেশন আছে?
ব্যবহারকারী 1814008

5
দ্বারা Going ডক্স এর Spark 2.x, df.withColumn(..)করতে যোগ করতে অথবা প্রতিস্থাপন উপর নির্ভর করে একটি কলাম colNameযুক্তি
Y2K-shubham

89

[সম্পাদনা: মার্চ ২০১ 2016: ভোটের জন্য ধন্যবাদ! যদিও সত্যই, এটি সর্বোত্তম উত্তর নয়, আমি মনে করি সমাধানগুলি ভিত্তিতে তৈরি করা হয়েছে withColumn, withColumnRenamedএবং castমেসেলম্যান, মার্টিন সেন এবং অন্যরা সহজ এবং পরিষ্কার পরিচ্ছন্ন করে রেখেছেন]।

আমি মনে করি আপনার দৃষ্টিভঙ্গি ঠিক আছে, মনে রাখবেন যে স্পার্কটি DataFrameসারিগুলির একটি (অপরিবর্তনীয়) আরডিডি, সুতরাং আমরা কখনই কোনও কলামটি প্রতিস্থাপন করে না , কেবল DataFrameপ্রতিটি স্কিমার সাথে নতুন করে তৈরি করি ।

ধরে নিচ্ছেন নীচের স্কিমা সহ আপনার কাছে একটি আসল ডিএফ রয়েছে:

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
 )

কলামের ধরণের পরিবর্তন করা বা অন্য থেকে নতুন ডেটাফ্রেম তৈরি করা এইভাবে লেখা যেতে পারে:

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কোডটি আরও পঠনযোগ্য এবং পুনরায় ব্যবহারযোগ্য make


26
এটি নিরাপদ বা দক্ষ নয়। নিরাপদ নয় কারণ একটি একক NULLবা ত্রুটিযুক্ত এন্ট্রি পুরো কাজটি ক্র্যাশ করবে। দক্ষ নয় কারণ ইউডিএফগুলি অনুঘটকদের কাছে স্বচ্ছ নয়। জটিল অপারেশনের জন্য ইউডিএফ ব্যবহার করা ঠিক ঠিক তবে এগুলি বেসিক টাইপ কাস্টিংয়ের জন্য ব্যবহার করার কোনও কারণ নেই। এই কারণেই আমাদের castপদ্ধতি রয়েছে ( মার্টিন সেনের উত্তর দেখুন )। ক্যাটালিস্টের কাছে জিনিসকে স্বচ্ছ করার জন্য আরও বেশি কাজ করা প্রয়োজন তবে প্রাথমিক সুরক্ষা রাখা Tryএবং Optionকাজ করা কেবল একটি বিষয় ।
শূন্য323

আমি "05-APR-2015" উদাহরণস্বরূপ স্ট্রিংয়ে তারিখ রূপান্তর সম্পর্কিত কোনও কিছুই দেখতে পাইনি
dbspace

3
আপনার withColumn()বিভাগটি এমন কোনও জেনেরিককে হ্রাস করার কোনও উপায় আছে যা সমস্ত কলামের মাধ্যমে পুনরাবৃত্তি করে?
বোর্ন

ধন্যবাদ শূন্য ৩৩৩৩, এটি পড়ে আমি বুঝতে পেরেছিলাম যে এখানে ইউডিএফ সমাধান কেন ক্র্যাশ হয়। কিছু মন্তব্য ইত্যাদি :) কিছু উত্তর চেয়ে ভাল
সাইমন Dirmeier

এমন কোনও উপায় আছে যার মাধ্যমে আমরা দুর্নীতিগ্রস্ত সারিটি জানতে পারি, তার অর্থ রেকর্ডিং যা কাস্টিংয়ের সময় ভুল ডেটা ধরণের কলাম রয়েছে। যেমন কাস্ট ফাংশন সেই ক্ষেত্রগুলি শূন্য করে তোলে
এতিশা

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 টি কলাম রয়েছে এবং স্কেলে মোটামুটি নতুন sure কিছু কলাম স্ট্রিং থাকা উচিত, কিছু ফ্লোতে কাস্ট করা উচিত।
দিমিত্রি স্মিরনভ

কীভাবে কোনও স্ট্রিংকে একটি তারিখে রূপান্তর করবেন উদাহরণস্বরূপ "25-APR-2016" কলামে এবং "20160302"
dbspace

@ দিমিত্রিস্মিরনভ আপনি কি কখনও উত্তর পেয়েছেন? আমারও একই প্রশ্ন. ;)
ইভান জমির

@ ইভানজামির দুর্ভাগ্যক্রমে নয়, আমি অন্যান্য পদক্ষেপে আরডিডি হিসাবে ডেটা ব্যবহার করতে সক্ষম হতে শিটোন অপারেশন করে শেষ করেছি। আমি আশ্চর্য হই যে এই দিনগুলিতে যদি আরও সহজ হয়ে যায় :)
দিমিত্রি স্মারনভ

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)
   }: _*
)

যদিও কোডের দৈর্ঘ্য আর এর চেয়ে কিছুটা দীর্ঘ। ভাষার ভার্বোসিসের সাথে এটির কোনও সম্পর্ক নেই। দ mutate, আর dataframe জন্য একটি বিশেষ ফাংশন যখন Scala মধ্যে আপনি যা করতে পারেন তার ভাবপূর্ণ ক্ষমতা সহজে অ্যাড-হক এক ধন্যবাদ।
কথায় কথায়, এটি সুনির্দিষ্ট সমাধানগুলি এড়ায়, কারণ আপনার নিজের ডোমেন ভাষাটি দ্রুত এবং সহজেই তৈরি করার জন্য ভাষার নকশা আপনার পক্ষে যথেষ্ট ভাল।


পার্শ্ব নোট: df.columnsআশ্চর্যজনক Array[String]পরিবর্তে Array[Column]এটির পরিবর্তে এটি সম্ভবত তারা এটি পাইথন পান্ডসের ডেটাফ্রেমের মতো দেখতে চান।


1
আপনি দয়া করে পাইপপার্কের সমতুল্য দিতে পারেন?
হরিত বিশ্বকর্মা

আমি আমার "বয়স" ক্ষেত্রের জন্য "সংজ্ঞা অবৈধ সূচনা" পাচ্ছি ith সাথে কলাম ("বয়স", $ "বয়স" cast কাস্টম (sql.tyype.DoubleType))। যেকোনো পরামর্শ?
ব্লুডলফিন

পারফরম্যান্সের কারণে আমরা যদি অনেকগুলি কলামে এই রূপান্তরগুলি করি তবে আপনার কি ডেটা ফ্রেমটি (ক্যাশে) রাখতে হবে, বা স্পার্ক তাদের অনুকূলিত করে দেওয়ার জন্য এটির কী প্রয়োজন নেই?
skjagini

আমদানি হতে পারে 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

স্ট্রিং থেকে পূর্ণসংখ্যায় ডেটাফ্রেমের ডেটাটাইপ সংশোধন করার জন্য জাভা কোড

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

এটি কেবলমাত্র বিদ্যমান (স্ট্রিং ডেটাটাইপ) পূর্ণসংখ্যায় ফেলে দেবে।


1
কোন ব্যাপার DataTypesমধ্যে sql.types! এটা DataType। তদ্ব্যতীত, কেউ কেবল আমদানি IntegerTypeএবং কাস্ট করতে পারে ।
এহসান এম। কেরমানি

@ এহসানএম.কর্মিনী আসলে ডেটাটাইপস। ইন্টেজার টাইপ একটি আইনী রেফারেন্স।
কিপিটার

1
@Cupitor DataTypes.IntegerTypeমধ্যে ব্যবহার করা হয় DeveloperAPI মোড এবং এটি এর v.2.1.0 মধ্যে স্থিতিশীল
এহসান এম Kermani

এটিই সেরা সমাধান!
সাইমন ডারমিয়ার

8

বছরটি স্ট্রিং থেকে ইনটে রূপান্তর করতে, আপনি সিএসভি পাঠককে নিম্নলিখিত বিকল্পটি যুক্ত করতে পারেন: "ইনফারশ্মিমা" -> "সত্য", ডেটাব্রিক্স ডকুমেন্টেশন দেখুন


5
এটি দুর্দান্তভাবে কাজ করে তবে ধরা পড়েছে যে পাঠককে অবশ্যই আপনার ফাইলটির দ্বিতীয় পাসটি করতে হবে
beefyhalo

@ বিফাইহলো একেবারে দাগ দিন, এর আশেপাশে কোনও উপায় আছে কি?
আয়ুশ

6

সুতরাং এটি কেবল তখনই কাজ করে যদি আপনার সমস্যা যেমন স্কিলসার্ভারের মতো একটি জেডিবিসি ড্রাইভারকে সঞ্চয় করতে পারে তবে এটি সিনট্যাক্স এবং প্রকারের সাথে ত্রুটিগুলির জন্য সত্যই সহায়ক।

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)

আপনি কি জাভাতে একই কোডটি প্রয়োগ করতে আমাকে সহায়তা করতে পারেন? এবং কীভাবে কাস্টমজেডবিসিডায়াল্টটি ডেটাফ্রেমে নিবন্ধন করবেন
অভিজিৎক্যাপস

ভার্টিকার সাথে আমিও একই কাজ করেছি, তবে স্পার্ক ২.১ থেকে। JDbcUtil আপনার প্রয়োজন কেবলমাত্র নির্দিষ্ট ডেটাটাইপ প্রয়োগ করতে। dialect.getJDBCType (dt)। orElse (getCommonJDBCType (dt))। getOrElse (নতুন অবৈধআর্গমেন্ট এক্সপেকশন নিক্ষেপ করুন (গুলি "D imp dt.simpleString J" এর জন্য জেডিবিসি টাইপ পেতে পারে না))
রডম্যান

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

কাস্ট, এফওয়াইআই, স্পার্ক ১.৪.১ এ কাস্ট পদ্ধতিটি ব্যবহার করার পরামর্শ দেওয়ার উত্তরগুলি নষ্ট হয়ে গেছে।

উদাহরণস্বরূপ, স্ট্রিং কলামযুক্ত একটি ডেটাফ্রেমের মান "8182175552014127960" যখন বড়িন্টে কাস্ট করা হয় তখন তার মান "8182175552014128100" থাকে

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

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

এই বাগটি সন্ধান করার আগে আমাদের প্রচুর সমস্যার মুখোমুখি হয়েছিল কারণ আমাদের প্রযোজনায় বিগিন্ট কলাম ছিল।


4
পিএসএস, আপনার স্পার্কটি আপগ্রেড করুন
মেসেলম্যান

2
@ মিসেলম্যান একটি ছোট বাগের জন্য উত্পাদনে স্পার্কের নতুন সংস্করণে আপগ্রেড হওয়া হাস্যকর।
sauraI3h

আমরা কি সবসময় ছোট বাগের জন্য সবকিছু আপগ্রেড করি না? :)
সিজারসোল


4

স্পার্ক এসকিউএল ২.৪.০ ব্যবহার করে আপনি এটি করতে পারেন:

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

স্পার্ক এসকিএল-এ কাস্ট ব্যবহার করে যে কোনও কলামের ডেটা ধরণের পরিবর্তন করতে পারে। টেবিলের নামটি টেবিল এবং এতে দুটি কলাম রয়েছে কেবল কলাম 1 এবং কলাম 2 এবং কলাম 1 ডেটা টাইপ পরিবর্তন করতে। প্রাক্তন-স্পার্ক.এসকিএল ("কাস্ট নির্বাচন করুন (ডাবল হিসাবে কলাম 1 নির্বাচন করুন) কলাম 1 নতুন নাম, টেবিল থেকে কলাম 2") ডাবল জায়গায় আপনার ডেটা টাইপ লিখুন।


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

অনেক উত্তর এবং খুব পুরো ব্যাখ্যা নেই

নিম্নলিখিত বাক্য গঠন স্পার্ক ২.৪ সহ ডেটাব্রিক্স নোটবুক ব্যবহার করে কাজ করে

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

নোট করুন যে আপনার কাছে থাকা এন্ট্রি ফর্ম্যাটটি নির্দিষ্ট করতে হবে (আমার ক্ষেত্রে "এমএম-ডিডি-ইয়াই") এবং আমদানি বাধ্যতামূলক কারণ টু_ডেটটি একটি স্পার্ক স্কয়ার ফাংশন হিসাবে

এছাড়াও এই বাক্য গঠনটি চেষ্টা করেও যথাযথ কাস্টের পরিবর্তে নাল পেয়েছে:

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

(দ্রষ্টব্য যদিও এটির বাক্য গঠনগতভাবে সঠিক হওয়ার জন্য আমাকে বন্ধনী এবং কোট ব্যবহার করতে হয়েছিল)


পিএস: আমাকে স্বীকার করতে হবে এটি একটি সিনট্যাক্স জঙ্গলের মতো, অনেকগুলি উপায়ের প্রবেশের পয়েন্ট রয়েছে এবং অফিসিয়াল এপিআই রেফারেন্সগুলির যথাযথ উদাহরণের অভাব রয়েছে।


1
সিনট্যাক্স জঙ্গল। হ্যাঁ. এই মুহুর্তে স্পার্কের পৃথিবী।
conner.xyz

1

আরও একটি সমাধান নিম্নরূপ:

1) "inferSchema" কে মিথ্যা হিসাবে রাখুন

২) সারিতে 'মানচিত্র' ফাংশন চলাকালীন আপনি 'asString' (قطار.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)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.