欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

在外存中实现分组的代码示例 文件计算外存分组代码集算器 

程序员文章站 2022-05-17 13:14:12
...

   在数据分析中,我们经常需要将数据分组,然后计算出各组的汇总值,或者在各组中分别计算。集算器中,可以用groups函数计算数据的分组汇总结果,更可以用group函数将表中记录分成多组,以便后续计算。但是,如果需要排序的数据量巨大,情况就不同了,这时是不能一次将它们读入内存的,这样普通的分组汇总,或者分组的方法就无法执行了,此时就可能需要使用外存分组。

  下面,先来准备一个大数据表,简单模拟1,000,000条手机用户的通话时长记录,存储在二进制文件PhoneBill中:


在外存中实现分组的代码示例
            
    
    
        文件计算外存分组代码集算器 
 

   其中,电话号码使用8位整数,前4位固定为1234,后4位随机生成。通话开始时间在2014年8月中随机产生。通话时长为整数,也随机生成,产生时使通话时长有90%的可能性为1分钟,最长20分钟。数据文件完成后,在B11中读出前1000条如下:


在外存中实现分组的代码示例
            
    
    
        文件计算外存分组代码集算器 
 

  现在,需要根据PhoneBill中的数据计算:

  ① 8月中每天所有用户的总通话时长以及每次通话的平均时长。

  ② 每位用户在8月的通话时长。

  ③ 分别将每天的通话记录存储到文件中。

  ④ 8月的每一天中,通话总时长最多的5位用户号码。

  先来看问题①,这首先需要将所有的订单数据按日期来分组汇总。因为8月一共只有31天,所以结果集并不是大数据,可以直接在内存中汇总计算:


在外存中实现分组的代码示例
            
    
    
        文件计算外存分组代码集算器 
 

   A2用A1中的二进制文本数据生成游标。A3计算游标中数据的分组汇总结果如下:


在外存中实现分组的代码示例
            
    
    
        文件计算外存分组代码集算器 
 

   因为结果本身的数据量并不大,计算分组汇总时,其实只需要将游标中的数据遍历一次,并不需要外存分组,直接用groups函数就能计算。这里的结果集并不庞大,可以直接获得结果,并不需要使用游标。计算每天中,每次通话的平均时间,需要先统计出每天的通话总时间及总次数,再进一步计算出平均通话时间,A4中获得的结果如下:


在外存中实现分组的代码示例
            
    
    
        文件计算外存分组代码集算器 
 

   问题②中的情况就不同了,由于用户量要比8月的天数多得多,这时就需要考虑分组汇总的结果是不是能一次返回到内存中。在这里,最多只有10,000个用户,并不算太多,只是以此来说明大数据结果集的计算情况。计算时,假设内存中只能容纳1000条记录:


在外存中实现分组的代码示例
            
    
    
        文件计算外存分组代码集算器 
 

   在计算大数据分组汇总结果时,需要用groupx函数,利用外存,根据设定的缓冲区行数来将游标内的数据逐步读出分组。A3中,计算游标中数据,按Phone分组;汇总计算总通话时长的结果,同时设定缓冲区行数为1000。大数据分组汇总的结果是游标,读取数据的方法和普通的游标完全相同。A3中的结果如下:


在外存中实现分组的代码示例
            
    
    
        文件计算外存分组代码集算器 
 

   在A4中读出了前1000名用户的总通话时长结果:


在外存中实现分组的代码示例
            
    
    
        文件计算外存分组代码集算器 
 

   另外,游标中的数据如果没有全部读完,需要调用cs.close()函数,以及时清理外存临时文件。

   问题③需要先将数据按照日期分组,再将每天的数据存储到文件中:


在外存中实现分组的代码示例
            
    
    
        文件计算外存分组代码集算器 
 

   使用groupn函数的大数据分组和普通的分组不同,需要在分组表达式中直接指定组号,在A3中,用订单日期的“日”作为组号。A3的函数中计算的结果与前面的分组汇总不同,返回的是游标序列,每个分组对应1个游标:


在外存中实现分组的代码示例
            
    
    
        文件计算外存分组代码集算器 
 

   在第4、5行的代码中,将每天的游标数据分别存到文件中。在A6中,选择了其中4日的数据,在A7中读出了前1000条记录如下:


在外存中实现分组的代码示例
            
    
    
        文件计算外存分组代码集算器 
 

   问题④仍然将数据按照日期分组,再在每个分组中执行分组汇总,最后根据汇总结果选出所需的用户号码:


在外存中实现分组的代码示例
            
    
    
        文件计算外存分组代码集算器 
 

   A3中,仍然在分组表达式中直接指定“日”作为组号,分组时返回的仍然是游标的序列:


在外存中实现分组的代码示例
            
    
    
        文件计算外存分组代码集算器 
 

   第4行到第6行的代码循环每个分组的游标数据,分别汇总每个用户每天的总通话时间,并根据汇总结果再次汇总出通话时间排在前5名的用户信息。需要注意的是,用汇总函数topx计算降序排序时,在排序表达式前加负号即可,如B5中的-TotalDuration。在结果中,选出通话时间最长的5个号码数据,并存入B3的序表中。循环完毕后,可以从B3中读出最终的结果如下:


在外存中实现分组的代码示例
            
    
    
        文件计算外存分组代码集算器 
 

   除了将总的话费数据分组,也可以继续使用问题③中生成的文件数据来处理这个问题。

  • 在外存中实现分组的代码示例
            
    
    
        文件计算外存分组代码集算器 
  • 大小: 54.2 KB
  • 在外存中实现分组的代码示例
            
    
    
        文件计算外存分组代码集算器 
  • 大小: 36.9 KB
  • 在外存中实现分组的代码示例
            
    
    
        文件计算外存分组代码集算器 
  • 大小: 23 KB
  • 在外存中实现分组的代码示例
            
    
    
        文件计算外存分组代码集算器 
  • 大小: 31 KB
  • 在外存中实现分组的代码示例
            
    
    
        文件计算外存分组代码集算器 
  • 大小: 41.6 KB
  • 在外存中实现分组的代码示例
            
    
    
        文件计算外存分组代码集算器 
  • 大小: 18.9 KB
  • 在外存中实现分组的代码示例
            
    
    
        文件计算外存分组代码集算器 
  • 大小: 7.2 KB
  • 在外存中实现分组的代码示例
            
    
    
        文件计算外存分组代码集算器 
  • 大小: 22.9 KB
  • 在外存中实现分组的代码示例
            
    
    
        文件计算外存分组代码集算器 
  • 大小: 31.6 KB
  • 在外存中实现分组的代码示例
            
    
    
        文件计算外存分组代码集算器 
  • 大小: 38.3 KB
  • 在外存中实现分组的代码示例
            
    
    
        文件计算外存分组代码集算器 
  • 大小: 32.5 KB
  • 在外存中实现分组的代码示例
            
    
    
        文件计算外存分组代码集算器 
  • 大小: 32.6 KB
  • 在外存中实现分组的代码示例
            
    
    
        文件计算外存分组代码集算器 
  • 大小: 34.7 KB
  • 在外存中实现分组的代码示例
            
    
    
        文件计算外存分组代码集算器 
  • 大小: 49.8 KB