AttributeError:“DataFrame”对象没有属性“map”

Posted

技术标签:

【中文标题】AttributeError:“DataFrame”对象没有属性“map”【英文标题】:AttributeError: 'DataFrame' object has no attribute 'map' 【发布时间】:2017-01-24 21:59:48 【问题描述】:

我想使用下面的代码转换火花数据框来添加:

from pyspark.mllib.clustering import KMeans
spark_df = sqlContext.createDataFrame(pandas_df)
rdd = spark_df.map(lambda data: Vectors.dense([float(c) for c in data]))
model = KMeans.train(rdd, 2, maxIterations=10, runs=30, initializationMode="random")

详细的错误信息是:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-11-a19a1763d3ac> in <module>()
      1 from pyspark.mllib.clustering import KMeans
      2 spark_df = sqlContext.createDataFrame(pandas_df)
----> 3 rdd = spark_df.map(lambda data: Vectors.dense([float(c) for c in data]))
      4 model = KMeans.train(rdd, 2, maxIterations=10, runs=30, initializationMode="random")

/home/edamame/spark/spark-2.0.0-bin-hadoop2.6/python/pyspark/sql/dataframe.pyc in __getattr__(self, name)
    842         if name not in self.columns:
    843             raise AttributeError(
--> 844                 "'%s' object has no attribute '%s'" % (self.__class__.__name__, name))
    845         jc = self._jdf.apply(name)
    846         return Column(jc)

AttributeError: 'DataFrame' object has no attribute 'map'

有谁知道我在这里做错了什么?谢谢!

【问题讨论】:

请记住,MLLIB 是围绕 RDD 构建的,而 ML 通常是围绕数据帧构建的。由于您似乎使用的是 Spark 2.0,我建议您从 ML 中查找 KMeans:spark.apache.org/docs/latest/ml-clustering.html @JeffL:我检查了 ml,我注意到输入必须是数据集,而不是数据框。所以我们需要再做一层转换,将data frame转换为dataset,才能使用ml? 我不再 100% 清楚区别,尽管在 Python 中我相信它几乎没有实际意义。事实上,如果你浏览 github 代码,在 1.6.1 中,各种数据框方法都在数据框模块中,而在 2.0 中,这些相同的方法在数据集模块中并且没有数据框模块。所以我认为你不会遇到数据框和数据集之间的任何转换问题,至少在 Python API 中是这样。 【参考方案1】:

您不能 map 数据帧,但您可以将数据帧转换为 RDD 并通过执行 spark_df.rdd.map() 进行映射。在 Spark 2.0 之前,spark_df.map 将别名为 spark_df.rdd.map()。使用 Spark 2.0,您必须首先显式调用 .rdd

【讨论】:

正确,这是 spark 2.0 中数据帧的主要变化之一 'RDD' 对象没有属性 'collectAsList' 这有主要的downsides:“转换为 RDD 会破坏 Dataframe 沿袭,没有谓词下推,没有列修剪,没有 SQL 计划和效率较低的 PySpark 转换。”有关更多详细信息和替代方案,请参阅我的答案。 公平地说,如果可能的话,您应该坚持使用 DF,并且几乎所有时间都应该这样做。根据您要执行的操作,将有不同的技术来完成此操作。但是,仍然可能存在转换为 RDD 的用例。【参考方案2】:

您可以使用df.rdd.map(),因为DataFrame 没有mapflatMap,但请注意使用implications 的df.rdd

转换为 RDD 会破坏 Dataframe 沿袭,没有谓词下推,没有列修剪,没有 SQL 计划和效率较低的 PySpark 转换。

你应该怎么做?

请记住,高级 DataFrame API 配备了许多替代方案。首先,您可以使用selectselectExpr

另一个example 正在使用explode 而不是flatMap(存在于RDD 中):

df.select($"name",explode($"knownLanguages"))
    .show(false)

结果:

+-------+------+
|name   |col   |
+-------+------+
|James  |Java  |
|James  |Scala |
|Michael|Spark |
|Michael|Java  |
|Michael|null  |
|Robert |CSharp|
|Robert |      |
+-------+------+

您也可以使用withColumnUDF,具体取决于用例,或DataFrame API 中的其他选项。

【讨论】:

以上是关于AttributeError:“DataFrame”对象没有属性“map”的主要内容,如果未能解决你的问题,请参考以下文章

AttributeError:“DataFrame”对象没有属性“map”

AttributeError:“DataFrame”对象没有属性“label”

AttributeError:模块“networkx”没有属性“from_pandas_dataframe”

Pandas 分析错误 AttributeError:“DataFrame”对象没有属性“profile_report”

Pandas 中的 Concat 2 列 - AttributeError:“DataFrame”对象没有属性“concat”

Unpickling 包含 pandas 数据框的字典会引发 AttributeError:“Dataframe”对象没有属性“_data”