栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

如何高效处理分析大文件

如何高效处理分析大文件

题记:

我们可能会遇到需要对一个很大的文件的某一行进行去重,排序,或者对两个文件进行合并等。本文主要测试了几种不同的方案,并进行比较。

场景: 对4百万数据的CSV文件进行去重

测试环境:MacBook Pro Intel Core i9 16GB Memory

测试文件:

# total lines
$ wc -l test.csv
42013405 test.csv
$ ls -lh test.csv
-rw-r--r--@ 1 haofan  staff   448M Nov  6 22:29 test.csv
$ head -4 test.csv
id
202105261
202105261
202105262
  • 方案一:linux 命令,  用时:186s
    • time sort -u test.csv > deup.csv
      186.88s user 11.05s system 97% cpu 3:22.14 total
  • 方案二: Python pandas, 代码如下, 大概耗时60s, 其中大部分时间花在写数据到磁盘上,因为是I/O bound。
    • import pandas as pd
      import logging
      logging.basicConfig(level=logging.DEBUG,
                          format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s')
      
      logging.info("Start reading files...")
      
      table_file = "~/Desktop/test/test.csv"
      test_csv = pd.read_csv(table_file, encoding='utf_8', low_memory=False)
      
      logging.info("Start running dedup...")
      
      test_csv = test_csv.drop_duplicates()
      
      logging.info("Start output...")
      test_csv.to_csv('dedup.csv', sep=" ", header=False, index=False)
      # np.savetxt("numpytotxt.csv", test_csv.values, fmt='%d') # take 37s.
      # test_csv.to_pickle('dedup.csv') # take 1s
      test_csv.reset_index().to_feather('dedup.csv') # take 2s
      logging.info("Finish all...")
      
      # 运行结果:用时大概60s 主要耗时在写数据到disk上, disk 写入大概耗时30s
      python test.py
      2021-11-06 22:57:11,552 - test.py[line:10] - INFO: Start reading files...
      2021-11-06 22:57:16,900 - test.py[line:15] - INFO: Start running dedup...
      2021-11-06 22:57:29,343 - test.py[line:19] - INFO: Start output...
      2021-11-06 22:58:02,648 - test.py[line:21] - INFO: Finish all...
      

      也查过其他写数据到磁盘上更快的方式,测试代码如上, 结果如下。因为feather或pickle是经过压缩的数据格式,输出的文件是二进制文件,必须用python才可读。但是因为平台不支持这种feather或者pickle的数据格式,只能用csv的数据格式。

      • to_feather: 只耗时2s,就可以把数据写入磁盘

      • to_pickle: 只耗时1s,就可以把数据写入磁盘。

  • 方案三:导入本地mysql,通过sql命令去执行。发现import data 超级慢大概要十几分钟,import data后,执行一次count的query,要耗时1分钟。

    • # 启动mysql
      docker run --name mysql -v /Users/haofan/code/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=haofan -d mysql
      # login mysql
      docker exec -it mysql bash
      # create DB
      create DATAbase test;
      use test
      # create table
      CREATE TABLE IF NOT EXISTS `users`(
         `id` VARCHAr(40) NOT NULL,
         PRIMARY KEY ( `id` )
      )ENGINE=InnoDB DEFAULT CHARSET=utf8;
      
      # allow import data from disk
      SET GLOBAL local_infile=1;
      
      docker exec -it mysql bash
      # import data
      mysqlimport --ignore-lines=1 
                  --fields-terminated-by='t' 
                  --local -u root 
                  -p test 
                  users.csv
      
      
      mysql> select count(*) from users;
      +----------+
      | count(*) |
      +----------+
      | 42013405 |
      +----------+
      1 row in set (53.22 sec)
  • 终极方案:导入大数据平台,hadoop. 

总结
  1. 如果对小文件的内容进行排序,最方便直接用shell sort. 
  2. 再大点的文件可以用python pandas,pandas最耗时的部分是写文件到磁盘。所以最好用pickle后者feather的数据格式。
  3. 再大的文件,如果追求高效率,只能用大数据平台。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/439161.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号