Chinaunix

标题: 大文件处理的设计问题 [打印本页]

作者: tuyajie    时间: 2015-03-13 22:51
标题: 大文件处理的设计问题
本帖最后由 tuyajie 于 2015-03-13 22:58 编辑

各位大神,想请教一个大文件处理的问题。我有一个20G的CSV文件,有400列左右。
我想做一些基本的数据质量检查操作,比如判断这列是小数还是整数还是字符串,如果是数字型,输出每一列的最大值,最小值,平均值,以及NULL的数量

我写了个基本的awk。但是性能很差。4个小时还是没有输出。
我能想到的基本的优化是切割文件,split或者cut。我目前在试验cut的效能。
想请教各位大神遇到这种问题有没有别的思路能把性能提高一些?语言可以不限制。当然shell最好。

  1. awk 'BEGIN{FS=",";OFS=",";getline}
  2. {for(i=3;i<=NF;i++){
  3.     if($i=="" ){$i=0;nullCnt[i]++};
  4.     if($i>=max[i])(max[i]=$i);
  5.     if($i<=min[i])(min[i]=$i);
  6.     sum[i]=sum[i]+$i}
  7. }
  8. END{for(i in max)print i,max[i],min[i],sum[i],nullCnt[i],NR}' inputFile> result
复制代码

作者: lcz88990200    时间: 2015-03-13 23:03
对于大文件(100M以上),如需进行判断和运算,不建议使用SHELL,速度太慢了。
有一次我处理15G的文本,用SHELL花了3个多小时,后使用C进行处理,10多秒就出来了。
作者: zsszss0000    时间: 2015-03-13 23:51
看来C还是非常重要的,性能之王啊 回复 2# lcz88990200


   
作者: tuyajie    时间: 2015-03-14 00:28
能分享下你的脚本么。我的C是入门中的入门回复 2# lcz88990200


   
作者: aswjh    时间: 2015-03-16 10:40
本帖最后由 aswjh 于 2015-03-16 13:16 编辑

用go语言做了一个,不太熟,看看性能如何
用gccgo -g -o test test.go -O3比go的默认编译器要快30%

  1. package main

  2. import (
  3.     //"runtime"
  4.     "fmt"
  5.     "os"
  6.     "bufio"
  7.     "io"
  8.     "strings"
  9.     "strconv"
  10. )

  11. func run(fn string) {
  12.     fp, err := os.Open(fn)
  13.     defer fp.Close()
  14.     MAXCOL := 500
  15.     max := [500]int{}
  16.     min := [500]int{}
  17.     sum := [500]int{}
  18.     empty := [500]int{}
  19.     nr, colcnt := 0, 0
  20.     if err == nil {
  21.         buf := bufio.NewReader(fp)
  22.         bufio.NewReaderSize(buf, 6553600)
  23.         for {
  24.             data, _, err := buf.ReadLine()
  25.             if err != nil || err == io.EOF {
  26.                 break
  27.             }
  28.             nr++
  29.             if nr%1000000==0 {
  30.                 fmt.Println("处理到:", nr, "行")
  31.             }
  32.             cols := strings.Split(string(data), ",")
  33.             leng := len(cols)
  34.             for c := 3; c < leng; c++  {
  35.                 num, err := strconv.Atoi(cols[c])
  36.                 if c > colcnt {
  37.                     if err == nil {
  38.                         max[c], min[c], sum[c] = num, num, num
  39.                     } else {
  40.                         empty[c] = 1
  41.                     }
  42.                     colcnt = c
  43.                 } else {
  44.                     if err == nil {
  45.                         if num > max[c] {
  46.                             max[c] = num
  47.                         } else if num < min[c] {
  48.                             min[c] = num
  49.                         }
  50.                         sum[c] += num
  51.                     } else {
  52.                         min[c] = 0
  53.                         empty[c]++
  54.                     }
  55.                 }
  56.             }
  57.             for c := leng; c< MAXCOL; c++ {
  58.                 min[c] = 0
  59.                 empty[c]++
  60.             }
  61.         }
  62.         fmt.Println("处理结束.共", nr, "行")
  63.         for i, x := range sum {
  64.             if x > 0 || empty[i] < nr {
  65.                 fmt.Println(fmt.Sprintf("%d,%d,%d,%d,%d", i+1, max[i], min[i], x, empty[i]))
  66.             }
  67.         }
  68.     } else {
  69.         fmt.Print("打开文件出错:", fn)
  70.     }
  71. }

  72. func main() {
  73.     //runtime.GOMAXPROCS(5)
  74.     for _, f := range os.Args[1:] {
  75.         fmt.Println("正在处理:", f)
  76.         run(f)
  77.     }
  78. }

复制代码

作者: tuyajie    时间: 2015-03-16 10:42
我去试试,谢谢回复 5# aswjh


   
作者: aswjh    时间: 2015-03-16 10:52
刚才的有点问题,改了一下
作者: Georgescott    时间: 2015-08-24 17:17
我有另外一个问题,大神tuyajie 能解答下吗? 谢谢!

http://bbs.chinaunix.net/forum.p ... ;page=1#pid24439571
作者: substr函数    时间: 2015-08-25 15:59
回复 1# tuyajie

能贴出 2, 3 行 看看么
你的csv
   
作者: expert1    时间: 2015-08-25 16:17
既然是CSV,那excel来做吧,很快的。非常的基础
作者: reb00t    时间: 2015-08-25 17:10
为什么没人用大蟒蛇呢~
作者: tuyajie    时间: 2015-08-25 17:16
文件其实很简单。就是大~~
30GB吧。1000多列。全是些数字啊,小数啊,日期啊。
然后想做的就是取每一列的最大,最小,missing rate, count, countNotNull这样的统计信息。

目前是用hadoop在搞。但是总觉得单机上应该是能处理这样的事件
作者: MMMIX    时间: 2015-08-25 17:21
回复 12# tuyajie


    文件本身的大小不是问题, 关键要看你需要在内存中保存多少内容.
作者: ly5066113    时间: 2015-08-25 17:46
回复 12# tuyajie


装个SAS,一个 PROC UNIVARIATE 就可以了。
作者: tuyajie    时间: 2015-08-26 14:11
回复 14# ly5066113
SAS有免费的?装个学学去

   
作者: substr函数    时间: 2015-08-26 19:44
回复 10# expert1

既然是CSV,那excel来做吧,很快的。非常的基础
   

你确定吗?
excel 可以打开一个20G的CSV文件
作者: substr函数    时间: 2015-08-26 19:57
回复 10# expert1


大神,
你可以改变头像?

它看起来像一只鸡?
就是鸡?
作者: expert1    时间: 2015-08-27 09:25
不记得哪里找的图片了。。。回复 17# substr函数


   




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2