我正在学习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.word
和shakespeareDF["word"]
都不起作用,为什么col("word")
会这样做?
谢谢
答案 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仍将导致需要过滤的空字符串条目。它只是不会创建多个空字符串,其中输入中有连续的空格。