PySpark:将String类型的DataFrame列转换为Double时出现KeyError

Posted

技术标签:

【中文标题】PySpark:将String类型的DataFrame列转换为Double时出现KeyError【英文标题】:PySpark : KeyError when converting a DataFrame column of String type to Double 【发布时间】:2017-04-20 05:41:48 【问题描述】:

我正在尝试通过 PySpark 学习机器学习。我有一个数据集,其中有几个 String 列,其值为 True or False or Yes or No。我正在使用DecisionTree,我想将这些String 值转换为相应的Double 值,即True, Yes 应更改为1.0False, No 应更改为0.0。我看到了一个教程,他们做了同样的事情,我想出了这段代码

df = sqlContext.read.csv("C:/../churn-bigml-20.csv",inferSchema=True,header=True)

from pyspark.sql.types import DoubleType
from pyspark.sql.functions import UserDefinedFunction

binary_map = 'Yes':1.0, 'No':0.0, 'True':1.0, 'False':0.0
toNum = UserDefinedFunction(lambda k: binary_map[k], DoubleType())

csv_data = df.drop('State').drop('Area code') \
    .withColumn('Churn', toNum(df['Churn'])) \
    .withColumn('International plan', toNum(df['International plan'])) \
    .withColumn('Voice mail plan', toNum(df['Voice mail plan'])).cache()

但是当我运行它时,我得到了很多看起来像这样的错误。

  File "C:\..\spark-2.1.0\python\lib\pyspark.zip\pyspark\worker.py", line 70, in <lambda>
  File "C:\..\workspace\PyML\src\ModelBuilding.py", line 20, in <lambda>
    toNum = UserDefinedFunction(lambda k: binary_map[k], DoubleType())
KeyError: False

注意:我正在使用 Spark 2.1 和 Python 3.5 开发 PySpark,我猜我遵循的教程使用 spark 1.6 和 Python 2.7。所以如果这是 Python 语法问题之一,我不会。

【问题讨论】:

列中的字符串是否带有引号?...我认为原因可能是列中的字符串可能是“否”而不是“否” 不。我检查了数据集,他们没有 qoutes。它们只是普通的字符串值。 你为什么不使用 binary_map.get(k)?我认为它应该引发另一个使用 [] 访问字典的错误 我是 Python 新手。我正在学习 Python 和机器学习。我按照教程尝试了相同的流程并执行它。因此,如果您发现代码有任何问题/语法错误,请纠正我的错误。我想学习并纠正我的错误。 是的。现在添加了。 【参考方案1】:

我通过将映射部分更改为:

binary_map = 'Yes':1.0, 'No':0.0, True : 1.0, False : 0.0
toNum = UserDefinedFunction(lambda k: binary_map[k], DoubleType())

我刚刚从 True 和 False 中删除了引号。我认为这很奇怪,但是当我使用 print(df.printSchema()) 检查 DataFrame 的架构时,它显示具有 True 和 False 值的字段的类型为 boolean

架构

root
 |-- State: string (nullable = true)
 |-- Account length: integer (nullable = true)
 |-- Area code: integer (nullable = true)
 |-- International plan: string (nullable = true)
 |-- Voice mail plan: string (nullable = true)
  .
  .
  .
 |-- Customer service calls: integer (nullable = true)
 |-- Churn: boolean (nullable = true)

所以这就是我不得不去掉引号的原因。谢谢。

【讨论】:

确实如此。现在我明白我们需要关注细节。人们说“必须全面了解我们正在使用的数据”。现在我知道为什么了。无论如何,谢谢。 :)

以上是关于PySpark:将String类型的DataFrame列转换为Double时出现KeyError的主要内容,如果未能解决你的问题,请参考以下文章

所有列的 Pyspark 数据框数据类型由 UDF 更改为 String

Pyspark 将列类型从日期更改为字符串

在 pyspark 中比较不同数据框中的两列,分别为 String 和 Array<string> 类型

无法使用 Pyspark 2.4.4 读取 s3 存储桶中的镶木地板文件

pyspark 在循环中将数组转换为字符串

将 array<string> 转换为字符串 pyspark 数据帧