2010-05-05 3 views
3

나는 csv 및 xml 파일을 조작하는 데 사용되는 4 개의 비교적 복잡한 r 스크립트가 있습니다. 이들은 다른학과에서 독점적으로 연구하는 곳에서 만들어졌습니다.파일 조작을위한 R 또는 Python

데이터를 처리 할 때 r이 매우 빠르지 만 파일 조작에는 실제로 최적화되어 있지 않습니다. 이 스크립트를 파이썬으로 변환하면 속도가 상당히 빨라질 것으로 기대합니까? 아니면 시간 낭비일까요?

답변

10

정기적으로 R 및 Python으로 작성합니다. 필자는 쓰기, 읽기, 구문 분석을위한 Python 모듈을 사용, 유지 및 업데이트하기가 더 쉽다고 생각한다. 파이썬이 R의 색인 생성에 대한 항목 목록을 처리 할 수있는 방법과 같은 작은 점은 읽는 것이 훨씬 쉬워집니다.

언어 전환을 통해 상당한 속도 향상을 기대할 수 있습니다. 이 스크립트의 새로운 "관리자"가되어 파이썬이 이해하고 확장하기 쉽다는 것을 알게되면 나는 그것을 위해 말하십시오.

컴퓨터 시간이 저렴합니다 ... 프로그래머 시간이 비쌉니다. 다른 일을해야한다면 나에게는 그 (것)들과 함께 putz 무료 하루가 될 때까지 당신이 가진 것과 함께 그냥 절뚝 거릴 것입니다.

희망이 있습니다.

+0

+1 : R과 Python 모두에서 경험을 쌓은 저는 여러분과 완전히 동의합니다! – EOL

0

내 생각에 아마 시간이 많이 걸릴 것 같지 않다. 고급 언어를 비교할 때 언어의 오버 헤드는 일반적으로 성능 문제 때문에 발생하지 않습니다. 일반적으로 문제는 귀하의 알고리즘입니다.

저는 R에 익숙하지 않지만, 큰 덩어리의 데이터를 작은 용량의 덩어리보다 작은 덩어리 (적은 시스템 호출)로 읽으면 속도가 향상 될 수 있습니다. R이 이와 같은 것을 변경할 능력이 없다면 아마도이 기능 때문에 파이썬이 훨씬 더 빠를 수 있습니다.

1

어디에서 시간을 보냈는지 알 수 있습니다. R 스크립트가 디스크 IO에서 병목 현상이 발생한 경우 (이 경우 매우 가능) 직접 최적화 된 어셈블리로 다시 작성할 수 있으며 더 빠를 수 없습니다. 최적화와 함께 항상 그렇듯이, 당신이 먼저 측정하지 않으면, 당신은 단지 바람에 오줌을 질질뿐입니다. 디스크 IO에서 병목 현상이 없다면 언어를 변경하는 것보다 알고리즘을 개선하면 더 많은 이점을 얻을 수 있습니다.

+0

. 아주 웅변합니다. –

1

"파일 조작"이란 무엇입니까? 파일 이동, 삭제, 복사 등등에 대해 이야기하고 있습니까? 예를 들어, bash 등의 쉘을 사용할 것입니다. 데이터 읽기, 계산 수행, 새로운 파일 작성 , 등등. 그렇다면 파이썬이나 R을 사용할 수 있습니다. 유지 보수가 문제가되지 않는다면, 그냥 R로 남겨두고 다른 물고기를 튀김으로 발견 할 수 있습니다. 시간과 노력을 정당화하기위한 충분한 속도 향상을 보지 못할 것입니다. 그 코드를 포팅하는 중.

0

R 데이터 조작에는 규칙이 있습니다. 기본 사항은 다음과 같습니다

  1. 벡터화
  2. 사용 data.frames (예를 들어, 결국) 가능한 한 적은 R 시간 최적화 및 프로파일 링하고 많은 자원을 찾을 수에 대한

검색 도와주세요.

+0

Vectorise, 예. 데이터 프레임을 피하십시오. – hadley

+0

안녕하세요. 데이터 프레임을 피하는 것이 중요하지 않은 이유는 무엇입니까 (계산상의 이유로)? –

2

몇 주 전, 큰 (280MB) CSV file에서 일부 행을 추출하는 Python 스크립트를 작성했습니다. 보다 정확하게 ISIN 필드가있는 dbpedia의 회사에서 사용 가능한 모든 정보를 추출하려고했습니다.나중에 R에서 똑같은 방법을 시도했지만, 시도한 것처럼 열심히 노력한 R 스크립트는 python 스크립트 (10 분 대 내 오랜 랩톱에서 1 분)보다 10 배 더 많이 사용했습니다. 어쩌면 이것은 R에 대한 나의 지식 때문일 수 있는데,이 경우 스크립트를 더 빠르게 만드는 방법에 대한 어떤 힌트도 주시면 감사하겠습니다. 다음은 파이썬 코드 여기

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." 

하고 (난 더 이상에 해당하는 버전을 가지고 있지 않지만, csv 파일을 작성하는 dataframe을 대신 반환하고 ISIN 확인하지 않는 매우 유사) R 스크립트입니다 :

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 RAM 머신이 메모리가 부족하다고 생각했기 때문에 이것을했다. 나는이 제한없이 시도하지 않았다.