zoukankan      html  css  js  c++  java
  • 文本处理的小诀窍

    文本处理的小诀窍

    场景描述

    • 原始文本格式:

            pid1 kid1
            pid3 kid1
            pid1 kid2
            pid1 kid3
            pid2 kid3
            pid2 kid4
    
    • 需要统计的结果:每条pid可以跟哪几个kid关联,最终结果格式:

            pid1 kid1,kid2,kid3
            pid2 kid3,kid4
            pid3 kid1
    

    * 原始文本大概有2亿多行

    处理思路

    • 将文本按第一列排序,排序后效果:
      pid1 kid1
      pid1 kid2
      pid1 kid3
      pid2 kid3
      pid2 kid4
      pid3 kid3
    • 将第一列相同的行合并,效果:
      pid1 kid1,kid2,kid3
      pid2 kid3,kid4
      pid3 kid1
      

    具体解决代码

        # sort -k 1 -n src.txt > sort1.txt
        # cat sort1.txt | php -B '
              $pidtmp = 0;
              $kidtmp = array();
          ' -R '
              list($pid, $kid) = explode("	", $argn);
              if($pid != $pidtmp) {
                  echo "
    ".$pidtmp."	".implode(",", array_keys($kidtmp));
                  $pidtmp = $pid;
                  $kidtmp = array();
              }
              $kidtmp[$kid] = 1;
          '
    

    以上两条命令可实现需求,共耗时半个小时左右

    其它说明

    本需求中存在一个原始文档,这个文档是通过其它程序生成的。那么存在一个疑问,为什么其它程序生成文档时,不直接生成所需要的格式(即以上示例的最终格式),而是生成一个中间格式的文档。

    其实在设计之前的程序时,确实就是期望直接输出以上的最终文档,但出现一个问题就是这个最终文档要怎么存储,存mysql还是nosql。尝试过mysql,一共有2亿行结果,每一行就需要读、写一次mysql,时间成本太高。然后也尝试了redis,使用列表存储,每一行原数据,只需要写一次redis的列表,可以减少一次读,然而时间还是太长,所以才将中间结果输入到文本。再使用以上提到的2条命令将结果转换为最终格式,时间成本大降低。

    如果有另外一个程序需要根据pid来搜索以上生成的最终文档,可以借鉴另一篇文章 ,入口

  • 相关阅读:
    python实现指定目录下批量文件的单词计数:串行版本
    PythonPP+lambda:示例
    python面向对象编程基础
    《平凡的世界》读后感
    代码
    【转】提高沟通效果的十个技巧
    LODOP中page-break-before:always给div分页
    LODOP超文本简短问答和相关内容
    Lodop打印较大的超出纸张的图片
    Lodop打印设计矩形重合预览线条变粗
  • 原文地址:https://www.cnblogs.com/dormscript/p/5818399.html
Copyright © 2011-2022 走看看