python推数据及流处理扩展
来源:互联网 发布:淘宝开店装修 编辑:程序博客网 时间:2024/05/22 08:26
python对于“流”的处理以generator为主,这种方式适合拉数据,不适合推数据。
做个简单的扩展,totrg类似imap的推数据版本(可以一对一、一对多、一对零,完成类似imap、filter等功能),preduce类似reduce,groupto类似groupby的推数据版本。
fromsrc与rotrg对应,方便处理输入输出,fromto从输入读出发送到输出,支持标准输入输出、文件、list、generator,groupkv对groupby的扩展。
##coding:utf8import sysfrom itertools import imap,groupbydef coroutine(func): '''协程修饰器,调用一次被修饰的函数即可创建生成器,不用调用next函数''' def newfunc(*args,**kwargs): r = func(*args,**kwargs) r.next() return r return newfuncdef fromsrc(src,func=None,multi=False,fargs=()): '''从src读取,对接受的数据进行处理,之后作为生成器的数据,func为处理函数, multi表示是否func的输出为一对多''' if src == sys.stdin: for data in src: if func: if multi: for d in func(*((data.rstrip('\r\n'),)+fargs)): yield d else: yield func(*((data.rstrip('\r\n'),)+fargs)) else: yield data.rstrip('\r\n') elif type(src) == str: for data in open(src): if func: if multi: for d in func(*((data.rstrip('\r\n'),)+fargs)): yield d else: yield func(*((data.rstrip('\r\n'),)+fargs)) else: yield data.rstrip('\r\n') else: for data in src: if func: if multi: for d in func(*((data,)+fargs)): yield d else: yield func(*((data,)+fargs)) else: yield data@coroutinedef totrg(trg,func=None,multi=False,fargs=()): '''对接受的数据进行处理,之后发送到trg,func为处理函数, multi表示是否func的输出为一对多''' if trg == sys.stdout or trg == sys.stderr: while True: data = yield if func: if multi: for d in func(*((data,)+fargs)): print >> trg, d else: print >> trg, func(*((data,)+fargs)) else: print >> trg, data elif type(trg) == str: with open(trg,'a') as t: while True: data = yield if func: if multi: for d in func(*((data,)+fargs)): t.write(str(d)+'\n') else: t.write(str(func(*((data,)+fargs)))+'\n') else: t.write(str(data)+'\n') elif type(trg) == list: while True: data = yield if func: if multi: for d in func(*((data,)+fargs)): trg.append(d) else: trg.append(func(*((data,)+fargs))) else: trg.append(data) else: try: while True: data = yield if func: if multi: for d in func(*((data,)+fargs)): trg.send(d) else: trg.send(func(*((data,)+fargs))) else: trg.send(data) except StopIteration: stop(trg) def stop(outstream): '''结束协程处理''' try: if outstream: outstream.throw(StopIteration) except StopIteration: passdef fromto(src,trg,func=None,multi=False,fargs=()): '''从src读取数据,发送到trg,可用func对数据进行处理, multi表示是否func的输出为一对多''' t = totrg(trg) s = fromsrc(src) for data in s: if func: if multi: for d in func(*((data,)+fargs)): t.send(d) else: t.send(func(*((data,)+fargs))) else: t.send(data) stop(trg)@coroutinedef preduce(redfunc,outstream,init=None,finalfunc=None,initargs=()): '''把数据用redfunc汇总,可以用init初始化、finalfunc做结束操作, init可以是函数,也可以是值''' result = None if init != None: result = init(*initargs) if callable(init) else init try: while True: data = (yield) if result == None: result = data else: result = redfunc(result,data) except StopIteration: if finalfunc and callable(finalfunc): finalfunc(result) else: outstream.send(result)def groupkv(instream,keyfunc=None,valuefunc=None): '''类似groupby函数,keyfunc对数据进行分组,valuefunc提取数据''' grp = groupby(instream,keyfunc) for k,vs in grp: yield k,imap(valuefunc,vs)@coroutinedef groupto(outstream,grpfunc,keyfunc=None,valuefunc=None): '''类似groupby函数,数据处理采取推方式, 用keyfunc对数据进行分组,有新分组时发送通知给outstream, 同一组数据用grpfunc创建协程发送到该协程处理''' grpstream = None lastkey = None try: while True: data = (yield) key = keyfunc(data) if keyfunc else data value = valuefunc(data) if valuefunc else data if grpstream and key == lastkey: grpstream.send(value) else: stop(grpstream) grpstream = grpfunc(key) grpstream.send(value) outstream.send((key,grpstream)) lastkey = key except StopIteration: stop(grpstream)@coroutinedef null(): '''丢到数据''' while True: yield@coroutinedef groupsum(outstream,keyindex,valueindex): '''分组求和的例子''' def dealvalues(key): def sendresult(result): outstream.send((key,result)) return preduce(int.__add__,null(),0,sendresult) grp = groupto(null(),dealvalues,itemgetter(keyindex),itemgetter(valueindex)) try: while True: data = yield grp.send(data) except StopIteration: stop(grp)
transfer('test.txt',sys.stdout) #从文件读输出到屏幕
分组求和:
keysums = []grps = groupsum( totrg(keysums), 0, 1 )
fromto( [("a",1),("a",2),("b",3),("b",4),("c",5)], grps )
结果:[('a', 3), ('b', 7), ('c', 5)]
0 0
- python推数据及流处理扩展
- JDBC扩展--处理大数据详解及源码
- python分析数据的处理过程及总结
- python的exec()及扩展
- 用python抓取数据及画图(用python处理文字数据)
- python 处理csv数据
- python处理二进制数据
- python处理xml数据
- python处理json数据
- Python处理Excel数据
- python处理二进制数据
- Python处理Excel数据
- python处理二进制数据
- python 处理大数据
- python处理数据脚本
- python处理二进制数据
- python处理JSON数据
- python处理log数据
- hibernate标签 property-ref 属性
- Hibernate一对多示例
- 【Storm总结-5】Twitter Storm: Transactional Topolgoy简介
- 第十一周 项目6:回文素数(2)
- 明白了为啥样式前面老是加 -webkit-、-moz-等
- python推数据及流处理扩展
- Highcharts js统计图插件
- Code Vs 1010 过河卒
- Linux下*.tar.gz文件解压缩命令
- 安卓训练-开始-支持不同的设备-支持不同的平台版本
- MTK Android添加驱动模块
- 在Ubuntu中安装Cassandra
- Adobe Reader 下添加书签功能
- Erlang Shell JCL 远程进入 接入Erlang控制台的几种方法