集算器如何处理文本计算——结构化运算

读入控制

从逗号分隔的有标题结构化文本D.csv中读入4列:name,sex,age,phone;其中phone是全数字但必须读成字符串类型。

        

A

1

=file(“D.csv”).import@t(name,sex,age,phone:string;”,”)

import函数有丰富的参数和选项控制是否有标题、分隔符、读入的列及其数据类型,大部分结构化文本的读入可以一句完成。

这个结果可以用JDBC以ResultSet对象的形式返回给Java主程序去再处理,这对熟悉JDBC的程序员很方便,相当于把文本当作数据库表读入。

文本很大时也可以用游标执行同样动作

        

A

1

=file(“D.csv”).cursor@t(name,sex,age,phone:string;”,”)

 

2

=A1.fetch(100)

取100行

游标也可以用JDBC返回给Java主程序。

 

大文本还可以用分段的方式读入:

        

A

 B

1

=file(“D.csv”).import@tz(;”,”,2:4)

平均分作4段,读入第2段

集算器按文件字节数分段保证读入效率(按行分段需要遍历前面所有行),对于分段点所在行采用了去头补尾的策略,即把本段第一行舍弃,最后一行补全,这样保证每一段都是由完整行构成的,不会出现半行的情况,确保信息的正确性。

游标也支持分段读入。

 

不关心读入次序时(求和计数等运算),还可以采用内置并行的方案提高性能:

        

A

1

=file(“D.csv”).import@tm(name,sex,age,phone:string;”,”)

这时集算器会启动多线程自动对文件分段后并行读入,因为文本解析较慢,采用并行读入能很大程度地利用CPU多核的能力,大幅度降低文本解析时间。

 

常规运算

从文本D.csv中找出男25岁以上、女23岁以上的人:1) 按姓名排序列出;2) 按性别分组计算平均年龄; 3) 列出所有出现过的姓氏(不考虑复姓)。

        

A

1

=file(“D.csv”).import@t(name,sex,age;”,”)

 

2

=A1.select(sex==”M”&&age>=25||sex==”F”&&age>=23)

过滤

3

=A2.sort(name)

排序

4

=A2.groups(sex;avg(age):age)

分组汇总

5

=A2.id(left(name,1))

唯一值

集算器提供了丰富的结构化计算功能,一定程度上可以将文本作为数据库表进行运算,在无数据库的场景下也能获得类似SQL的计算能力。

 

数据量大时这些计算也都可以基于游标工作:

        

A

1

=file(“D.csv”).cursor@tm(name,sex,age;”,”)

 

2

=A1.select(sex==”M”&&age>=25||sex==”F”&&age>=23)

过滤

3

=A2.sortx(name)

排序

3

=A2.groups(sex;avg(age):age)

分组汇总

3

=A2.groupx(left(name,1);)

唯一值

4

=A3.fetch(…)

取出结果

与内存运算不同的是,游标只能遍历一次,上述排序分组运算只能执行某一个,再执行另一个时需要重建游标。

 

用文本D.csv中phone列的第4至7位可到文本P.txt中aid列查出该号码的所在地area列,列出D.csv中电话号码所在地是北京的记录。

        

A

1

=file(“D.csv”).import@tm(;”,”)

2

=file(“P.txt”).import@t(id,area)

3

=A1.derive(mid(phone,4,3):aid).switch(aid,A2:aid)

4

=A3.select(aid.area==”Beijing”)

将A1改成用游标也可以针对大文本工作。

 

集算器用指针处理外键连接,引用更方便。也可以用类似SQL的join方法:

        

A

1

=file(“D.csv”).import@tm(;”,”)

 

2

=file(“P.txt”).import@t(id,area)

 

3

=join@1(A1,left(phone,4,3);A2,aid)

@1表示左连接

4

=A3.select(#2.area==”Beijing”).(#1)

 

 

文件比对

找出文本T1.txt中id列在T2.txt中出现和不出现的值。

        

A

1

=file(“T1.txt”).import@ti(id)

 

2

=file(“T2.txt”).import@ti(id)

 

3

=A1^A2

交集,即T1和T2共有的值

4

=A1\A2

差集,即T1中有而T2中没有的值

比对列值直接用集合交差运算即可。

 

找出文本T1.txt中id列在T2.txt中出现和不出现的行。

        

A

1

=file(“T1.txt”).import@t().sort(id)

2

=file(“T2.txt”).import@t().sort(id)

3

=[A1,A2].merge@i(id)

交集,T1的行,其id在T2中也有

4

=[A1,A2].merge@d(id)

差集,T1的行,其id在T2中没有

要获得整行需要先排序再用归并法。

 

找出文本T1.txt和T2.txt中哪些行的id值相同但其它列不同的行:

        

A

 B

1

=file(“T1.txt”).import@t()

 

2

=file(“T2.txt”).import@t()

 

3

=join(A1,id;A2,id)

用等值连接,不匹配的丢弃

4

=A3.select(cmp(#1,#2)!=0)

找出记录不同的

用join可以将数据按某列对齐。

 

不能装下内存的大文本也可以使用归并和连接的方法比对,但都需要先排序:

        

A

 B

1

=file(“T1.txt”).cursor@t().sortx(id)

2

=file(“T2.txt”).cursor@t().sortx(id)

3

=[A1,A2].merge@xi(id)

交集,T1的行,其id在T2中也有

4

=[A1,A2].merge@xd(id)

差集,T1的行,其id在T2中没有

merge@x表示针对有序的游标归并,大文件外存排序要用sortx()。

        

A

1

=file(“T1.txt”).cursor@t().sortx(id)

 

2

=file(“T2.txt”).cursor@t().sortx(id)

 

3

=join@x(A1,id;A2,id)

用等值连接,不匹配的丢弃

4

=A3.select(#1.array()!=#2.array())

 

join@x表示针对有序的游标连接。

posted on 2015-10-27 08:50  hivehooker  阅读(372)  评论(0编辑  收藏  举报

导航