Structured Streaming 简单数据处理——读取CSV并提取列关键词

╄→гoц情女王★ 提交于 2019-11-29 09:39:52

前言

近日想学学Spark 比较新的Structured Streaming ,百度一轮下来,全都是千篇一律的wordcount ,很是无语。只好自己摸索,除了Dataframe的Select和Filter 操作还能做些什么处理。因为用的Python,用过Pandas,摸索中,想转Pandas去处理,结果readStream并不支持直接toPandas()这个方法。最后翻来官方API,发现了还有Dataframe还有一个强大的操作,并且能够在readStream中使用,那就是——UDF。

环境准备

  • Hadoop 2.8.5
  • Spark 2.4.3
  • Python 3.7.3
  • jieba (jieba分词工具,提供了TF-IDF关键词提取方法,pip install jieba)

程序下面的代码都是在交互式环境下执行,即pyspark下。

数据准备

id title_zh content_zh publish_date  
         
         

假设CSV数据如上表格所示,分别表示文章id,标题,内容,发布时间。

有如下需求:提取标题的关键词,并将关键词添加到新列。(本来还有提取文章关键词,原理其实一样,就不多写了)

读取数据

读取csv文件有两步:定义schema,按照schema读取文件。

定义schema:

                本例中,id为Integer类型,publish_date为TimestampType类型,其余为StringType。首先引入部分依赖:

from pyspark.sql.functions import udf
from  pyspark.sql.types import StructType,StringType,IntegerType,TimestampType

                定义一个StructType:

sdf=StructType().add('id',IntegerType())
sdf.add('title_zh',StringType()).add('content_zh',StringType())
sdf.add('publish_date',TimestampType())

                设置监听文件夹,该文件夹当产生新的CSV文件时,spark会自动读取到stream,路径需要指明是hdfs:///或者file:///

rcsv=spark.readStream.options(header='true',multiline='true',inferSchema='true').schema(sdf).csv("file:///home/moon/文档/test")

                 通过rcsv.isStreaming判断是否是Stream

处理数据

处理数据分3步:

  1. 定义关键词提取方法,定义方法选取系数最高的词,剔除纯数字
  2. 将提取方法构造成Udf
  3. 利用Dataframe的“转换”方法调用Udf

最后选择输出模式、输出目地,输出结果。下面直接上代码,具体看注释:

#引入jieba依赖
import jieba
import jieba.analyse

def getTopWord(words):
    if(words==[]):
        return ""
    wordc=0
    while (words[wordc].isdigit()):
        if(wordc>=len(words)-1):
            return words[wordc]
        wordc+=1
    return words[wordc]

    
def getKeyword(ctx):
    #extract_tags方法有个可选topK=N参数,提取N个词,但是这里要剔除纯数字要用另外的方法,所以使用它的默认值
    word=getTopWord(jieba.analyse.extract_tags(ctx,withWeight=False))
    return word;

#参数为(方法名,返回类型),方法可以是lambda,返回类型为必填。调用时,逐行调用udf
getKeyword_udf=udf(getKeyword,StringType())


#对['title_zh']这一列使用udf方法,并使用select生成新列,alias()定义别名,最后得到新的readStream
ncsv=rcsv.select('id','title_zh',getKeyword_udf(rcsv['title_zh']).alias('title_zh_keyword'),'publish_date')

#设置输出模式为update,还有complete和Append;输出到命令行。更详细我也说不清,建议看官方文档。
query=ncsv.writeStream.outputMode('update').format("console").start()

结果

上面的全部代码,在pyspark中,一条条输入代码就行了,路径根据自己实际替换,数据内容和类型可以根据自己喜好做调整。

本例的CSV文件如图:

执行结果图如下:

 

PS:小姐姐微博@只是简言 ,侵删~(反正我是不信有人会来举报我~)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!