R实现大文本文件数据分组汇总的方法

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

R实现大文本文件数据分组汇总的方法

使用R语言对文件数据分组汇总是很普遍的操作,但有时我们会遇到比较大的文件,这类文件的计算结果较小,但源数据太大,无法全部放入内存进行计算,只能采用分批读取、分批计算、拼合结果的办法来解决。下面用一个例子来说明R实现大文件数据分组汇总的方法。

有个1G的文件sales.txt,存储着大量订单记录,我们要对CLIENT字段分组并对AMOUNT 字段汇总。该文件的列分割符为“\t”,前几行数据如下:

R语言解决方案

1con <- file("E: \\sales.txt", "r")

2result=read.table(con,nrows=100000,sep="\t",header=TRUE)

3result<-aggregate(result[,4],list(result[,2]),sum)

4while(nrow(databatch<-read.table(con,header=FALSE,nrows=100000,sep="\t",s=c(" ORDERID","Group.1","SELLERID","x","ORDERDATE")))!=0) {

5databatch<-databatch[,c(2,4)]

6result<-rbind(result,databatch)

7result<-aggregate(result[,2],list(result[,1]),sum)

8}

9close(con)

部分计算结果

代码解读:

1行:打开文件句柄。

2-3行:读入第一批的十万条数据,分组汇总后存入result。

4-8行:循环读数。每批次读入十万行数据,存入databatch变量。然后取第2和第4个字段,即“CLIENT”和“AMOUNT”。接着将databatch拼合到result中,再执行分组运算。

可以看到,同一时刻只有databatch和result会占用内存,其中databatch有十万条记录,

result是汇总结果,而汇总结果通常较小,不会超出内存。

11行:关闭文件句柄。

注意事项:

关于数据框。R语言的数据框不直接支持大文件,因此要用循环语句来辅助解决。具体的算法是:读一批数据,拼合到数据框result,对result分组汇总,再读下一批数据。可以看到,循环语句这部分的代码略显复杂。

关于列名。由于第一行数据是列名,因此第一批数据可以用header=TRUE直接设置列名,但后续数据没有列名,所以要用header=FALSE来读数。使用header=FALSE时,默认的列名是V1、V2…,而分组汇总后的默认列名是Group.1、x,因此还要用s来改名,这样才能使两者结构一致,方便后续的合并。列名这部分很容易出错,值得注意。

替代方案:

同样的算法也可以用Python、集算器、Perl等语言来实现。和R语言一样,这几种语言都可以实现大文本文件的分组汇总,以及后续的结构化数据计算。下面简单介绍集算器和Python的解决方案。

集算器会自动分批处理数据,程序员无需用循环语句手工控制,因此代码非常简洁:

cursor是集算器中用于结构化数据计算的数据类型,和数据框的用法差不多,但对大文件和复杂计算更擅长。另外,代码中的@t选项表示文件的第一行是列名,因此之后的计算可以直接用列名,这一点比较方便。

Python的代码结构和R差不多,也是手工控制循环,但python本身缺乏数据框或cursor 等结构化数据类型,因此代码更底层些:

1f rom itertools import groupby

2f rom operator import itemgetter

3r esult = []

4m yfile = open("E:\\sales.txt",'r')

5B UFSIZE = 10240000

6m yfile.readline()

7l ines = myfile.readlines(BUFSIZE)

8v alue=0

9w hile lines:

10for line in lines:

11record=line.split('\t')

12result.append([record[1],float(record[3])])

13result=sorted(result,key=lambda x:(x[0])) #分组前的排序

14batch=[]

15for key, items in groupby(result, itemgetter(0)): #使用groupby函数分组

16value=0

17for subItem in items:value+=subItem[1]

18batch.append([key,value]) #最后把汇总结果拼成二维数组

19result=batch

20lines = myfile.readlines(BUFSIZE)

21m yfile.close()

除了上述的二维数组,Python也可以用第三方包来实现,比如pandas就有类似数据框的结构化数据对象。pandas可以简化代码,和R的算法差不多,但pandas对大文件的支持同样有限,仍然需要编写循环完成。

相关文档
最新文档