簡體   English   中英

如何在 PySpark 中將數據框列從 String 類型更改為 Double 類型?

[英]How to change a dataframe column from String type to Double type in PySpark?

我有一個列為字符串的數據框。 我想在 PySpark 中將列類型更改為 Double 類型。

以下是我做的方式:

toDoublefunc = UserDefinedFunction(lambda x: x,DoubleType())
changedTypedf = joindf.withColumn("label",toDoublefunc(joindf['show']))

只是想知道,這是正確的方法嗎,因為在運行邏輯回歸時,我遇到了一些錯誤,所以我想知道,這是否是造成麻煩的原因。

這里不需要 UDF。 Column已經提供了帶有DataType實例cast方法

from pyspark.sql.types import DoubleType

changedTypedf = joindf.withColumn("label", joindf["show"].cast(DoubleType()))

或短字符串:

changedTypedf = joindf.withColumn("label", joindf["show"].cast("double"))

其中規范的字符串名稱(也可以支持其他變體)對應於simpleString值。 所以對於原子類型:

from pyspark.sql import types 

for t in ['BinaryType', 'BooleanType', 'ByteType', 'DateType', 
          'DecimalType', 'DoubleType', 'FloatType', 'IntegerType', 
           'LongType', 'ShortType', 'StringType', 'TimestampType']:
    print(f"{t}: {getattr(types, t)().simpleString()}")
BinaryType: binary
BooleanType: boolean
ByteType: tinyint
DateType: date
DecimalType: decimal(10,0)
DoubleType: double
FloatType: float
IntegerType: int
LongType: bigint
ShortType: smallint
StringType: string
TimestampType: timestamp

例如復雜類型

types.ArrayType(types.IntegerType()).simpleString()   
'array<int>'
types.MapType(types.StringType(), types.IntegerType()).simpleString()
'map<string,int>'

通過使用與輸入列相同的名稱,保留列的名稱並避免添加額外的列:

from pyspark.sql.types import DoubleType
changedTypedf = joindf.withColumn("show", joindf["show"].cast(DoubleType()))

給定的答案足以解決問題,但我想分享另一種可能引入新版本 Spark 的方式(我不確定)所以給定的答案沒有抓住它。

我們可以使用col("colum_name")關鍵字訪問 spark 語句中的列:

from pyspark.sql.functions import col
changedTypedf = joindf.withColumn("show", col("show").cast("double"))

PySpark 版本:

df = <source data>
df.printSchema()

from pyspark.sql.types import *

# Change column type
df_new = df.withColumn("myColumn", df["myColumn"].cast(IntegerType()))
df_new.printSchema()
df_new.select("myColumn").show()

解決方案很簡單 -

toDoublefunc = UserDefinedFunction(lambda x: float(x),DoubleType())
changedTypedf = joindf.withColumn("label",toDoublefunc(joindf['show']))

其他答案的一個問題(取決於您的 Pyspark 版本)是withColumn的使用。 至少在 v2.4.4 中觀察到了性能問題(請參閱此線程)。 spark 文檔提到了關於withColumn的內容:

這種方法在內部引入了一個投影。 因此,多次調用它(例如,通過循環以添加多個列)可能會生成大計划,從而導致性能問題甚至 StackOverflowException。 為避免這種情況,請同時對多個列使用 select。

一般來說,實現select的推薦用法的一種方法是:

from pyspark.sql.types import *
from pyspark.sql import functions as F

cols_to_fix = ['show']
other_cols = [col for col in joindf.columns if not col in cols_to_fix]
joindf = joindf.select(
    *other_cols,
    F.col('show').cast(DoubleType())
)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM