[英]Casting string to ArrayType(DoubleType) pyspark dataframe
我在火花中有一個 dataframe 具有以下架構:架構:
StructType(List(StructField(id,StringType,true),
StructField(daily_id,StringType,true),
StructField(activity,StringType,true)))
列活動是一個字符串,示例內容:
{1.33,0.567,1.897,0,0.78}
我需要將列 Activity 轉換為 ArrayType(DoubleType)
為了完成這項工作,我運行了以下命令:
df = df.withColumn("activity",split(col("activity"),",\s*").cast(ArrayType(DoubleType())))
dataframe 的新架構相應更改:
StructType(List(StructField(id,StringType,true),
StructField(daily_id,StringType,true),
StructField(activity,ArrayType(DoubleType,true),true)))
但是,數據現在看起來像這樣: [NULL,0.567,1.897,0,NULL]
它將字符串數組的第一個和最后一個元素更改為 NULL。 我不明白為什么 Spark 使用 dataframe 這樣做。
請問這里有什么問題可以幫忙嗎?
非常感謝
因為
下面的代碼沒有替換{
& }
df.withColumn("activity",F.split(F.col("activity"),",\s*")).show(truncate=False)
+-------------------------------+
|activity |
+-------------------------------+
|[{1.33, 0.567, 1.897, 0, 0.78}]|
+-------------------------------+
當您嘗試將這些{1.33
& 0.78}
字符串值轉換為DoubleType
時,您將得到null
為 output。
df.withColumn("activity",F.split(F.col("activity"),",\s*").cast(ArrayType(DoubleType()))).show(truncate=False)
+----------------------+
|activity |
+----------------------+
|[, 0.567, 1.897, 0.0,]|
+----------------------+
改變這個
df.withColumn("activity",split(col("activity"),",\s*").cast(ArrayType(DoubleType())))
至
from pyspark.sql import functions as F
from pyspark.sql.types import ArrayType
from pyspark.sql.types import DoubleType
df.select(F.split(F.regexp_replace(F.col("activity"),"[{ }]",""),",").cast("array<double>").alias("activity"))
發生這種情況是因為您的第一個和最后一個字母是括號本身,因此將其轉換為 null
testdf.withColumn('activity',f.split(f.col('activity').substr(f.lit(2),f.length(f.col('activity'))-2),',').cast(t.ArrayType(t.DoubleType()))).show(2, False)
嘗試這個-
val df = Seq("{1.33,0.567,1.897,0,0.78}").toDF("activity")
df.show(false)
df.printSchema()
/**
* +-------------------------+
* |activity |
* +-------------------------+
* |{1.33,0.567,1.897,0,0.78}|
* +-------------------------+
*
* root
* |-- activity: string (nullable = true)
*/
val processedDF = df.withColumn("activity",
split(regexp_replace($"activity", "[^0-9.,]", ""), ",").cast("array<double>"))
processedDF.show(false)
processedDF.printSchema()
/**
* +-------------------------------+
* |activity |
* +-------------------------------+
* |[1.33, 0.567, 1.897, 0.0, 0.78]|
* +-------------------------------+
*
* root
* |-- activity: array (nullable = true)
* | |-- element: double (containsNull = true)
*/
使用 Spark SQL 的簡單方法(無正則表達式):
df2=(df1
.withColumn('col1',expr("""
transform(
split(
substring(activity,2,length(activity)-2),','),
x->DOUBLE(x))
"""))
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.