2011-03-21 2 views
0

알려주세요. 학습 점으로 사용하겠습니다. 나는 초보자이다.느린 파이썬 파일 I : O; 루비는 이것보다 더 잘 실행됩니다. 잘못된 언어를 얻었습니까?

25mb 파일을 여러 개의 작은 파일로 분할하려고합니다.

친절한 전문가가 나에게 루비 줄을 줬다. 그것은 아름답게 빨리 작동합니다. 그래서, 나는 파이썬 스크립트로 그것을 모방 배우기 위해서. 이것은 3 발 고양이처럼 느리게 움직입니다. 왜 누군가가 저에게 말할 수 있는지 궁금합니다.

내 파이썬 스크립트

##split a file into smaller files 
########################################### 
def splitlines (file) : 
     fileNo=0001 
     outFile=open("C:\\Users\\dunner7\\Desktop\\Textomics\\Media\\LexisNexus\\ele\\newdocs\%s.txt" % fileNo, 'a') ## open file to append 
     fh = open(file, "r") ## open the file for reading 
     mylines = fh.readlines() ### read in lines 
     for line in mylines: ## for each line 
         if re.search("Copyright ", line): # if the line is equal to the regex 
          outFile.close() ## close the file 
          fileNo +=1 #and add one to the filename, starting to read lines in again 
         else: # otherwise 
          outFile=open("C:\\Users\\dunner7\\Desktop\\Textomics\\Media\\LexisNexus\\ele\\newdocs\%s.txt" % fileNo, 'a') ## open file to append 
          outFile.write(line)   ## then append it to the open outFile   
     fh.close() 

구루의 루비 1.9 스크립트

g=0001 
f=File.open(g.to_s + ".txt","w") 
open("corpus1.txt").each do |line| 
    if line[/\d+ of \d+ DOCUMENTS/] 
    f.close 
    f=File.open(g.to_s + ".txt","w") 
    g+=1 
    end 
    f.print line 
end 
+1

속도와 관련된 번호를 게시 할 수 있습니까? –

+2

스크립트는 다른 작업을 수행합니다. 파이썬 스크립트는 작성하는 거의 모든 행에 대해 새 파일을 엽니 다. 그것은 확실히 느리지 만, 당신은 무엇을 기대합니까? –

+0

또한 Ruby 스크립트는 출력을 위해 여러 파일을 엽니 다. –

답변

0

파이썬 코드는 IO 정규식 및하지로 인해 속도가 느려질 수 있습니다. 정규식 반복적으로 사용하는 경우

  • 항상 경로 이름/대신 \의 사용

    def splitlines (file) : 
        fileNo=0001 
        outFile=open("newdocs/%s.txt" % fileNo, 'a') ## open file to append 
        reg = re.compile("Copyright ") 
        for line in open(file, "r"): 
        if reg.search("Copyright ", line): # if the line is equal to the regex 
         outFile.close() ## close the file 
         outFile=open("newdocs%s.txt" % fileNo, 'a') ## open file to append 
         fileNo +=1 #and add one to the filename, starting to read lines in again 
    
        outFile.write(line)   ## then append it to the open outFile   
    

    여러 노트는

  • , 그것은 당신이 re.search를해야합니까
  • 컴파일보십시오? 또는 re.match?

UPDATE :

  • @Ed. S :
  • @Winston Ewert 촬영 지점 : 원래 루비 코드
+0

정규 표현식 사용을 중단 한 날은 적은 양의 텍스트에 정규 표현식을 적용하는 것이 디스크에서 파일을 읽는 것보다 느린 날입니다. 나는 당신이이 것에 대한 당신의 추측에 대해 틀렸다고 생각합니다. –

+0

파일을 계속 열지 않도록 코드를 수정하면 훨씬 빠릅니다. –

2

내가 스크립트가 너무 느린 이유를 추측에 근접하도록 업데이트 된 코드는 각 라인에 새 파일 기술자를 열 것입니다. 전문가의 루비 스크립트를 보면, 구분 기호가 일치하는 경우에만 출력 파일이 닫히고 열립니다.

이와 대조적으로 파이썬 스크립트는 읽은 모든 줄에 대해 새로운 파일 설명자를 엽니 다 (그리고 btw는 닫지 않습니다). 파일을 열려면 커널과 대화해야하므로 상대적으로 느립니다. 내가 제안

또 다른 변화는

fh = open(file, "r") ## open the file for reading 
mylines = fh.readlines() ### read in lines 
for line in mylines: ## for each line 

이 변화

fh = open(file, "r") 
for line in fh: 

에, 당신은 메모리에 전체 파일을 읽을 수 있지만 블록 후 차단하지 않는 변경하는 것입니다. 25MiB 파일로는 중요하지 않지만 큰 파일로 개의 파일을 다치게 할 수 있으며 우수 사례 (및 코드가 적음)).

6

스크립트가 느린 데는 여러 가지 이유가 있습니다. 주된 이유는 작성한 거의 모든 행에 대해 출력 파일을 다시 여는 것입니다. 오래된 파일은 (파이썬 가비지 컬렉션으로 인해) 새로운 파일을 열 때 암묵적으로 닫히기 때문에, 쓰기 버퍼는 작성하는 모든 단일 행에 대해 플러시되며, 이는 상당히 비쌉니다.

A는 청소 및

def file_generator(): 
    file_no = 1 
    while True: 
     f = open(r"C:\Users\dunner7\Desktop\Textomics\Media" 
       r"\LexisNexus\ele\newdocs\%s.txt" % file_no, 'a') 
     yield f 
     f.close() 
     file_no += 1 

def splitlines(filename): 
    files = file_generator() 
    out_file = next(files) 
    with open(filename) as in_file: 
     for line in in_file: 
      if "Copyright " in line: 
       out_file = next(files) 
      out_file.write(line) 
     out_file.close() 
+0

+1 코드를 찾아 내면 이전에 알지 못했던 몇 가지 새로운 파이썬 기능을 배웠습니다. 내가 좋아하는 여러 가지 이유 중 하나. – JoshAdel

+0

그냥 누군가가 내 코드를 알아 내야 만 매혹! 나는 정신 차리고 !!, 나는 직업을 바꿔야한다고 생각하니 ??? 아니, 좋아. – rosser

+0

@Rosser - 코드가 아닙니다 - 무엇이 잘못되었는지 분명했습니다. 나는 이전에 Sven이 파일을 읽는 데 사용했던''with ''as '구조체를 보지 못했습니다. 그것은 파이썬에 새로운 슈퍼가 아니지만, 전에 그것을 가로 질러 오지 않았다. – JoshAdel

0

rosser 될 것입니다 스크립트의 버전을 수정

내장 된 식별자 등의 개체 코드에서 (파일, splitlines)의 이름을 사용하지 마십시오

다음 코드는 자신의 코드가 적용되는 효과를 나타냅니다. out_file은 닫는 신호를 구성하는 'Copyright'가 포함 된 행없이 닫힙니다.

,210

() 함수 writelines를 사용하는 경우에의 마지막 줄 out_file로 의 폐쇄를 트리거 out_file.write(line)

if li: 블록의 반복으로보다 빠른 실행을 얻었다 거기 의도 읽기 파일에 '저작권'이 포함되어 있지 않습니다.

def splitfile(filename, wordstop, destrep, file_no = 1, li = []): 
    with open(filename) as in_file: 
     for line in in_file: 
      if wordstop in line: 
       with open(destrep+str(file_no)+'.txt','w') as f: 
        f.writelines(li) 
       file_no += 1 
       li = [] 
      else: 
       li.append(line) 
     if li: 
      with open(destrep+str(file_no)+'.txt','w') as f: 
       f.writelines(li)