无法在Apache Spark上访问我的dataframe列

时间:2016-07-06 01:44:47

标签: apache-spark

我正在学习Spark并且想知道为什么我无法访问我的列,这是我正在运行的命令:

shakespeareDF.select(explode(split(shakespeareDF.sentence, " ")).alias("word")).filter(shakespeareDF.word != "")

shakespeareDF.select(explode(split(shakespeareDF.sentence, " ")).alias("word")).filter(shakespeareDF["word"] != "")

这两个命令都给了我一个AttributeError: 'DataFrame' object has no attribute 'word',但我不知道为什么。

有趣的是,这有效shakespeareDF.select(explode(split(shakespeareDF.sentence, " ")).alias("word")).filter(col("word") != "")

所以我的问题是:为什么shakespeareDF.wordshakespeareDF["word"]都不起作用,为什么col("word")会这样做?

谢谢

3 个答案:

答案 0 :(得分:2)

这两种行为都没有什么好笑或奇怪的。

您在创建和别名上执行拆分的第一个DataFrame。这将使用该列创建一个新的DataFrame。因此,当您从第一个DataFrame内部调用新创建的列时,它显然不会存在,这就是您收到错误的原因。

现在,关于你的第二次尝试,你试图访问列字,无论它是DataFrame,哪个spark会在新创建的DataFrame模式中找到。

我希望这能解决你的困惑。

答案 1 :(得分:2)

使用shakespeareDF [" word"]表示shakespeareDF中的 列。使用col(" word")只表示列字, HAS NOT 尚未绑定到DataFrame。

使用绑定列意味着无法链接方法调用。

explosedDF = shakespeareDF.select(explode(split(shakespeareDF.sentence, " ")).alias("word"))
explosedDF.filter(explosedDF["word"] != "")

答案 2 :(得分:1)

再加上Rockie Yang的回答,你还需要保存过滤功能的输出。也可能也分裂在多个空格上,而不仅仅是单个空格,因为后者将导致N个空格的序列被分成N-1个空字符串。 (然后,后面的过滤器会删除空字符串,但最好不要在第一时间生成它们。)

testSentenceDF = sqlContext.createDataFrame([('Some spaces',), ('are  repeated',), ('rather    unnecessarily.',)], ['sentence'])
testWordsNaiveDF = testSentenceDF.select(explode(split(testSentenceDF.sentence, ' ')).alias('word'))
testWordsNaiveDF.show()

#+--------------+
#|          word|
#+--------------+
#|          Some|
#|        spaces|
#|          here|
#|              |
#|           are|
#|      repeated|
#|              |
#|              |
#|              |
#|unnecessarily.|
#+--------------+

testWordsImprovedDF = testSentenceDF.select(explode(split(testSentenceDF.sentence, '\s+')).alias('word'))
testWordsImprovedDF.show()

#+--------------+
#|          word|
#+--------------+
#|          Some|
#|        spaces|
#|          here|
#|           are|
#|      repeated|
#|unnecessarily.|
#+--------------+

testWordsNaiveFilteredDF = testWordsNaiveDF.filter(testWordsNaiveDF.word != '')
testWordsNaiveFilteredDF.show()

#+--------------+
#|          word|
#+--------------+
#|          Some|
#|        spaces|
#|          here|
#|           are|
#|      repeated|
#|unnecessarily.|
#+--------------+

请注意,即使拆分空白序列,如果您的输入有空行或带有开头或尾随空格的行,那么您的split / explode仍将导致需要过滤的空字符串条目。它只是不会创建多个空字符串,其中输入中有连续的空格。