如何读取固定宽度格式的大数据?我读了这个问题并尝试了一些提示,但所有答案都是针对分隔数据(如.csv),而这不是我的理由.数据有558MB,我不知道有多少行.
我正在使用:
dados <- read.fwf('TS_MATRICULA_RS.txt', width=c(5, 13, 14, 3, 3, 5, 4, 6, 6, 6, 1, 1, 1, 4, 3, 2, 9, 3, 2, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 4, 11, 9, 2, 3, 9, 3, 2, 9, 9, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1), stringsAsFactors=FALSE, comment.char='',
colClasses=c('integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'character', 'character', 'character',
'integer', 'integer', 'character', 'integer', 'integer', 'character', 'integer', 'character', 'character', 'character', 'character', 'character', 'character',
'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character',
'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'integer',
'integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'character', 'integer', 'integer', 'character', 'character', 'character',
'character', 'integer', 'character', 'character', 'character', 'character', 'character', 'character', 'character', 'character'), buffersize=180000)
Run Code Online (Sandbox Code Playgroud)
但是读取数据需要30分钟(并计算......).有什么新建议吗?
A5C*_*2T1 11
如果没有关于您的数据的足够详细信息,很难给出具体答案,但这里有一些想法可以帮助您入门:
首先,如果您使用的是Unix系统,则可以使用该wc命令获取有关文件的一些信息.例如,它wc -l TS_MATRICULA_RS.txt会告诉您文件中有多少行,wc -L TS_MATRICULA_RS.txt并将报告文件中最长行的长度.这可能有用.同样,head并且tail可以让您检查文本文件的第一行和最后10行.
第二,一些建议:既然看起来你知道每个字段的宽度,我会推荐两种方法中的一种.
csvkit+您最喜欢的方法来快速读取大数据csvkit是一组用于处理CSV文件的Python工具.其中一个工具是in2csv,它采用固定宽度格式的文件与"模式"文件相结合,以创建可与其他程序一起使用的适当CSV.
模式文件本身是一个包含三列的CSV文件:(1)变量名,(2)起始位置和(3)宽度.一个例子(来自in2csv手册页)是:
column,start,length
name,0,30
birthday,30,10
age,40,3
Run Code Online (Sandbox Code Playgroud)
创建该文件后,您应该可以使用以下内容:
in2csv -f fixed -s path/to/schemafile.csv path/to/TS_MATRICULA_RS.txt > TS_MATRICULA_RS.csv
Run Code Online (Sandbox Code Playgroud)
从那里,我建议用fread"data.table"或使用来查看数据sqldf.
sqldf使用substrsqldf在像你这样的大型数据文件上使用实际上应该非常快,并且您可以获得能够准确指定要使用的内容的好处substr.
同样,这将期望您有一个可用的模式文件,如上所述.获得架构文件后,您可以执行以下操作:
temp <- read.csv("mySchemaFile.csv")
## Construct your "substr" command
GetMe <- paste("select",
paste("substr(V1, ", temp$start, ", ",
temp$length, ") `", temp$column, "`",
sep = "", collapse = ", "),
"from fixed", sep = " ")
## Load "sqldf"
library(sqldf)
## Connect to your file
fixed <- file("TS_MATRICULA_RS.txt")
myDF <- sqldf(GetMe, file.format = list(sep = "_"))
Run Code Online (Sandbox Code Playgroud)
由于您知道宽度,因此您可以跳过模式文件的生成.从宽度来看,它只是一点点的工作cumsum.这是一个基本的例子,建立在第一个例子的基础上read.fwf:
ff <- tempfile()
cat(file = ff, "123456", "987654", sep = "\n")
read.fwf(ff, widths = c(1, 2, 3))
widths <- c(1, 2, 3)
length <- cumsum(widths)
start <- length - widths + 1
column <- paste("V", seq_along(length), sep = "")
GetMe <- paste("select",
paste("substr(V1, ", start, ", ",
widths, ") `", column, "`",
sep = "", collapse = ", "),
"from fixed", sep = " ")
library(sqldf)
## Connect to your file
fixed <- file(ff)
myDF <- sqldf(GetMe, file.format = list(sep = "_"))
myDF
unlink(ff)
Run Code Online (Sandbox Code Playgroud)
小智 9
该的LaF包是非常快的读取固定宽度的文件相当不错.我每天使用它来加载包含30列的+/- 100Mio记录的文件(没有那么多的字符列 - 主要是数字数据和一些因素).它非常快.所以这就是我要做的.
library(LaF)
library(ffbase)
my.data.laf <- laf_open_fwf('TS_MATRICULA_RS.txt',
column_widths=c(5, 13, 14, 3, 3, 5, 4, 6, 6, 6, 1, 1, 1, 4, 3, 2, 9, 3, 2, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 4, 11, 9, 2, 3, 9, 3, 2, 9, 9, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1), stringsAsFactors=FALSE, comment.char='',
column_types=c('integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'categorical', 'categorical', 'categorical',
'integer', 'integer', 'categorical', 'integer', 'integer', 'categorical', 'integer', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical',
'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical',
'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'integer',
'integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'categorical', 'integer', 'integer', 'categorical', 'categorical', 'categorical',
'categorical', 'integer', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical', 'categorical'))
my.data <- laf_to_ffdf(my.data.laf, nrows=1000000)
my.data.in.ram <- as.data.frame(my.data)
Run Code Online (Sandbox Code Playgroud)
PS.我开始使用LaF软件包,因为我对read.fwf的缓慢感到恼火,因为我最初用来解析数据的PL/SQL PostgreSQL代码变得很难维护.
这是一个使用新包的纯R解决方案readr,由2015年4月发布的Hadley Wickham和RStudio团队创建.更多信息请点击此处.代码就像这样简单:
library(readr)
my.data.frame <- read_fwf('TS_MATRICULA_RS.txt',
fwf_widths(c(5, 13, 14, 3, 3, 5, 4, 6, 6, 6, 1, 1, 1, 4, 3, 2, 9, 3, 2, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 4, 11, 9, 2, 3, 9, 3, 2, 9, 9, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1)),
progress = interactive())
Run Code Online (Sandbox Code Playgroud)
的优点 read_fwf{readr}
readr基于LaF但却出人意料地更快.它已经证明是在R中读取固定宽度文件的禁食方法column_types因为它们将从输入的前30行进行估算.