R还是Python用于文件操作
我有四个比较复杂的R脚本,用来处理CSV和XML文件。这些脚本是由另一个部门创建的,他们只使用R语言。
我了解到,虽然R在处理数据时速度很快,但在文件操作方面并不是特别优化。如果我把这些脚本转换成Python,能期待速度有明显提升吗?还是说这样做没什么意义?
6 个回答
要知道时间花在哪里。如果你的R脚本在读取或写入硬盘的时候很慢(在这种情况下很有可能),那么即使你把它们重写成手动优化的汇编语言,速度也可能不会更快。优化的时候,记得先测量一下,不然就像是在对着风撒尿,没什么用。如果不是因为硬盘的问题,那么改善算法可能比换语言更有效。
几周前,我写了一个Python脚本,用来从一个很大的(280MB)CSV文件中提取一些行。更具体地说,我想提取所有在dbpedia中有ISIN字段的公司的信息。后来我尝试用R语言做同样的事情,但无论我怎么努力,R脚本的运行时间是Python脚本的10倍(在我这台比较旧的笔记本上,Python只用了1分钟,而R用了10分钟)。这可能是因为我对R的了解不够,如果是这样的话,我希望能得到一些建议,让脚本运行得更快。以下是Python代码:
from time import clock
clock()
infile = "infobox_de.csv"
outfile = "companies.csv"
reader = open(infile, "rb")
writer = open(outfile, "w")
oldthing = ""
isCompany = False
hasISIN = False
matches = 0
for line in reader:
row = line.strip().split("\t")
if len(row)>0: thing = row[0]
if len(row)>1: key = row[1]
if len(row)>2: value = row[2]
if (len(row)>0) and (oldthing != thing):
if isCompany and hasISIN:
matches += 1
for tup in buf:
writer.write(tup)
buf = []
isCompany = False
hasISIN = False
isCompany = isCompany or ((key.lower()=="wikipageusestemplate") and (value.lower()=="template:infobox_unternehmen"))
hasISIN = hasISIN or ((key.lower()=="isin") and (value!=""))
oldthing = thing
buf.append(line)
writer.close()
print "finished after ", clock(), " seconds; ", matches, " matches."
这是R脚本(我没有对应的版本了,但有一个非常相似的,它返回一个数据框而不是写入CSV文件,并且没有检查ISIN):
infile <- "infobox_de.csv"
maxLines=65000
reader <- file(infile, "r")
writer <- textConnection("queryRes", open = "w", local = TRUE)
writeLines("thing\tkey\tvalue\tetc\n", writer)
oldthing <- ""
hasInfobox <- FALSE
lineNumber <- 0
matches <- 0
key <- ""
thing <- ""
repeat {
lines <- readLines(reader, maxLines)
if (length(lines)==0) break
for (line in lines) {
lineNumber <- lineNumber + 1
row = unlist(strsplit(line, "\t"))
if (length(row)>0) thing <- row[1]
if (length(row)>1) key <- row[2]
if (length(row)>2) value <- row[3]
if ((length(row)>0) && (oldthing != thing)) {
if (hasInfobox) {
matches <- matches + 1
writeLines(buf, writer)
}
buf <- c()
hasInfobox <- FALSE
}
hasInfobox <- hasInfobox || ((tolower(key)=="wikipageusestemplate") && (tolower(value)==tolower("template:infobox_unternehmen")))
oldthing <- thing
buf <- c(buf, line)
}
}
close(reader)
close(writer)
readRes <- textConnection(queryRes, "r")
result <- read.csv(readRes, sep="\t", stringsAsFactors=FALSE)
close(readRes)
result
我明确做的一件事是将readLines限制在最多65000行。我这样做是因为我担心我的500MB内存的机器会用完内存。至于不加这个限制的情况,我没有尝试过。
我经常用R和Python这两种语言写代码。我发现Python的模块在写、读和解析信息方面更容易使用、维护和更新。比如,Python处理列表的方式比R的索引方式要简单得多,这让代码更容易阅读。
我很怀疑换语言会让你的代码运行速度有明显提升。如果你要成为这些脚本的新“维护者”,而且觉得Python更容易理解和扩展,那我建议你就用Python。
电脑的运行时间便宜……程序员的时间却很贵。如果你还有其他事情要做,那我建议你先继续用现在的代码,等到有空的时候再去修改它们。
希望这些对你有帮助。