【问题标题】:Efficient way to transform several columns to string in PySpark在 PySpark 中将多列转换为字符串的有效方法
【发布时间】:2018-10-26 05:50:27
【问题描述】:

关于 SO (link 1, link 2, link 3, ...) 如何将单个变量转换为 string 类型在 PySpark 中类推:

from pyspark.sql.types import StringType    
spark_df = spark_df.withColumn('name_of_column', spark_df[name_of_column].cast(StringType()))

但是,当您有多个列要转换为string 类型时,有几种方法可以实现:

使用for 循环——我的代码中的成功方法:

简单的例子:

to_str = ['age', 'weight', 'name', 'id']
for col in to_str:
  spark_df = spark_df.withColumn(col, spark_df[col].cast(StringType()))

这是一种有效的方法,但我认为不是我正在寻找的最佳方法。

使用列表推导 -- 在我的代码中不成功:

我的错误示​​例:

spark_df = spark_df.select(*(col(c).cast("string").alias(c) for c in to_str))

不成功,因为我收到错误消息:

TypeError: 'str' 对象不可调用

然后我的问题是:在我的示例中,根据列名列表(如 to_str),在 PySpark 中将多列转换为字符串的最佳方法是什么?

提前感谢您的建议。

事后澄清编辑:

感谢@Rumoku 和@pault 的反馈:

两行代码都正确:

spark_df = spark_df.select(*(col(c).cast("string").alias(c) for c in to_str)) # My initial list comprehension expression is correct.

spark_df = spark_df.select([col(c).cast(StringType()).alias(c) for c in to_str]) # Initial answer proposed by @Rumoku is correct.

我收到了来自PySpark 的错误消息,因为我之前将对象to_str 的名称更改为col。正如@pault 解释的那样:col(具有所需字符串变量的列表)与列表理解的函数col 具有相同的名称,这就是PySpark 抱怨的原因。只需将 col 重命名为 to_str,然后更新 spark-notebook 即可解决所有问题。

【问题讨论】:

  • Spark 是惰性的,因此,您的 for 循环将构建单个查询并稍后执行。就性能而言,for 循环和列表推导式之间应该没有太大区别。
  • 嗨@Rumoku,感谢您的回答。你知道哪一个是 PySpark 中列表理解选项的正确语法,但在我的情况下不起作用?我使用的行是: spark_df = spark_df.select(*(col(c).cast("string").alias(c) for c in to_str)),错误消息是:“TypeError: 'str' object is not可调用”
  • 某处你将一个变量覆盖为字符串——我猜可能是col -> 你能做到print(type(col))吗?
  • @NuValue 就是这样。在您的 for 循环版本中,您将 col 分配给了一个字符串 (for col in to_str:)。然后您稍后尝试将其用作函数 (col(c).cast())。
  • @pault,你是完全正确的。我需要更新我的 Spark-Notebook,因为之后我删除了该对象的名称“col”。非常感谢!

标签: python types casting pyspark


【解决方案1】:

应该是:

spark_df = spark_df.select([col(c).cast(StringType()).alias(c) for c in to_str])

【讨论】:

  • 嗨@Rumoku,感谢您的回答。执行您的代码行后,我收到以下消息:“TypeError:'str' object is not callable”。我想知道函数 StringType() 是否是导致该行出现问题的函数?我以前自然地导入了模块:“from pyspark.sql.types import StringType”。
  • 在上一行执行print(spark_df)。我想知道它是否是数据框。
  • 谢谢,print(spark_df) 打印以下输出:DataFrame[ID: bigint, Source: string, NickName: string, EqType: bigint]
  • 你是如何导入col的?
  • 现在它完美运行@Rumoku,这是 Spark-Notebook 所需要的刷新。会将您的答案标记为正确。
【解决方案2】:

不确定解决方案中列表理解部分的 col() 是什么,但任何寻找解决方案的人都可以试试这个 -

from pyspark.sql.types import StringType 

to_str = ['age', 'weight', 'name', 'id']

spark_df = spark_df.select(
  [spark_df[c].cast(StringType()).alias(c) for c in to_str]
)

要将所有列替换为str 类型,请将to_str 替换为spark_df.columns

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-15
    • 1970-01-01
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多