Pyspark数据帧将多个列转换为浮点数

MAR*_*ARK 7 python apache-spark pyspark

我试图将数据帧的多个列从字符串转换为像这样的浮点数

df_temp = sc.parallelize([("1", "2", "3.4555"), ("5.6", "6.7", "7.8")]).toDF(("x", "y", "z"))
df_temp.select(*(float(col(c)).alias(c) for c in df_temp.columns)).show()
Run Code Online (Sandbox Code Playgroud)

但是我收到了错误

select() argument after * must be a sequence, not generator
Run Code Online (Sandbox Code Playgroud)

我无法理解为什么会抛出这个错误

mto*_*oto 17

float()不是Spark函数,你需要这个函数cast():

df_temp.select(*(col(c).cast("float").alias(c) for c in df_temp.columns))
Run Code Online (Sandbox Code Playgroud)

  • 需要pyspark.sql.functions导入col (2认同)

nim*_*sam 13

如果你想在不改变整个数据框的情况下构建一些列,你可以通过withColumn函数来实现:

for col_name in cols:
    df = df.withColumn(col_name, col(col_name).cast('float'))
Run Code Online (Sandbox Code Playgroud)

这将在cols列表中强制转换列类型,并按原样保留另一列.
注意:
withColumn函数用于根据列名替换或创建新列;
如果列名存在则会被替换,否则将被创建

  • 它可以工作,但是非常非常慢。有没有更好的方法将所有列转换为浮动类型? (3认同)

Jus*_*vis 9

如果要将多个列强制转换为浮动并保持其他列相同,可以使用单个 select 语句。

columns_to_cast = ["col1", "col2", "col3"]
df_temp = (
   df
   .select(
     *(c for c in df.columns if c not in columns_to_cast),
     *(col(c).cast("float").alias(c) for c in columns_to_cast)
   )
)
Run Code Online (Sandbox Code Playgroud)

我看到了 withColumn 答案,它可以工作,但由于 Spark 数据帧是不可变的,每个 withColumn 调用都会生成一个全新的数据帧