我有以下兩個場景之間共享的前奏代碼:
from pyspark.sql import SparkSession
from pyspark.sql.types import *
import pyspark.sql.functions as F
import pandas as pd
import numpy as np
spark = SparkSession.builder.getOrCreate()
df = pd.DataFrame({"col1": [1, 2, 3], "col2": [22.0, 88.0, np.nan]})
現在,我想轉換df成 pyspark 資料框(sdf)。當我在創建程序中嘗試通過模式"col2"隱式“強制轉換”時LongType,sdf它失敗了:
schema = StructType([StructField("col1", LongType()), StructField("col2", LongType())])
sdf = spark.createDataFrame(df[schema.fieldNames()], schema=schema)
錯誤:
TypeError:欄位 col2:LongType 不能接受型別為 <class 'float'> 的物件 22.0
但是,如果我運行以下代碼段,它就可以正常作業:
schema_2 = StructType(
[StructField("col1", LongType()), StructField("col2", FloatType())]
)
sdf = spark.createDataFrame(df[schema.fieldNames()], schema=schema_2)
cast_sdf = sdf.withColumn("col2", F.col("col2").cast(LongType()))
cast_sdf.show()
輸出:
---- ----
|col1|col2|
---- ----
| 1| 22|
| 2| 88|
| 3| 0|
---- ----
uj5u.com熱心網友回復:
將我的評論轉化為答案。
這實際上是 Spark 使用模式的方式。它并不特定于將 pandas 資料幀轉換為 pyspark 資料幀。將createDataframe方法與元組串列一起使用時,您將得到相同的錯誤:
import numpy as np
schema = StructType([StructField("col1", LongType()), StructField("col2", LongType())])
df = spark.createDataFrame([(1, 22.0), (2, 88.0), (3, np.nan)], schema)
# TypeError: field col2: LongType can not accept object 22.0 in type <class 'float'>
這也是傳遞模式時像 CSV 這樣的資料源的行為(盡管在讀取 CSV 時它不會因模式PERMISSIVE而失敗,但值被加載為 null)。因為模式不會自動轉換型別,它只是告訴 Spark 行中的每一列應該存在哪種資料型別。
因此,在使用模式時,您必須傳遞與指定型別匹配的資料或使用StringType不會失敗的資料,然后使用顯式轉換將列轉換為所需的型別。
schema = StructType([StructField("col1", LongType()), StructField("col2", StringType())])
df = spark.createDataFrame([(1, 22.0), (2, 88.0), (3, np.nan)], schema)
df = df.withColumn("col2", F.col("col2").cast("long"))
df.show()
# ---- ----
#|col1|col2|
# ---- ----
#| 1| 22|
#| 2| 88|
#| 3|null|
# ---- ----
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/405148.html
標籤:
上一篇:AzureSynapseAnalytics-高長度的列負載
下一篇:如何將陣列陣列轉換為火花中的列?
