Chinaunix
标题:
大文件处理的设计问题
[打印本页]
作者:
tuyajie
时间:
2015-03-13 22:51
标题:
大文件处理的设计问题
本帖最后由 tuyajie 于 2015-03-13 22:58 编辑
各位大神,想请教一个大文件处理的问题。我有一个20G的CSV文件,有400列左右。
我想做一些基本的数据质量检查操作,比如判断这列是小数还是整数还是字符串,如果是数字型,输出每一列的最大值,最小值,平均值,以及NULL的数量
我写了个基本的awk。但是性能很差。4个小时还是没有输出。
我能想到的基本的优化是切割文件,split或者cut。我目前在试验cut的效能。
想请教各位大神遇到这种问题有没有别的思路能把性能提高一些?语言可以不限制。当然shell最好。
awk 'BEGIN{FS=",";OFS=",";getline}
{for(i=3;i<=NF;i++){
if($i=="" ){$i=0;nullCnt[i]++};
if($i>=max[i])(max[i]=$i);
if($i<=min[i])(min[i]=$i);
sum[i]=sum[i]+$i}
}
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%
package main
import (
//"runtime"
"fmt"
"os"
"bufio"
"io"
"strings"
"strconv"
)
func run(fn string) {
fp, err := os.Open(fn)
defer fp.Close()
MAXCOL := 500
max := [500]int{}
min := [500]int{}
sum := [500]int{}
empty := [500]int{}
nr, colcnt := 0, 0
if err == nil {
buf := bufio.NewReader(fp)
bufio.NewReaderSize(buf, 6553600)
for {
data, _, err := buf.ReadLine()
if err != nil || err == io.EOF {
break
}
nr++
if nr%1000000==0 {
fmt.Println("处理到:", nr, "行")
}
cols := strings.Split(string(data), ",")
leng := len(cols)
for c := 3; c < leng; c++ {
num, err := strconv.Atoi(cols[c])
if c > colcnt {
if err == nil {
max[c], min[c], sum[c] = num, num, num
} else {
empty[c] = 1
}
colcnt = c
} else {
if err == nil {
if num > max[c] {
max[c] = num
} else if num < min[c] {
min[c] = num
}
sum[c] += num
} else {
min[c] = 0
empty[c]++
}
}
}
for c := leng; c< MAXCOL; c++ {
min[c] = 0
empty[c]++
}
}
fmt.Println("处理结束.共", nr, "行")
for i, x := range sum {
if x > 0 || empty[i] < nr {
fmt.Println(fmt.Sprintf("%d,%d,%d,%d,%d", i+1, max[i], min[i], x, empty[i]))
}
}
} else {
fmt.Print("打开文件出错:", fn)
}
}
func main() {
//runtime.GOMAXPROCS(5)
for _, f := range os.Args[1:] {
fmt.Println("正在处理:", f)
run(f)
}
}
复制代码
作者:
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