我有几十万个关键字放在文件4.txt中,想提取文件3.txt中含有关键字的行,保存到文件5.txt中.
文件3有200万行,我使用下面的代码可以实现我的要求,但是非常慢,一个下午还没运行完,谁有快一点的方法?
使用并行改如何改造呢?我看到这里有个并行的帖子,,与我的不同的事,我要同时读以及查询同一个文件,上述链接可以并行操作多个文件。
with open('3.txt', 'r') as f3, open('4.txt', 'r') as f4, open('result.txt', 'w') as f5:
a = [line.strip() for line in f4.readlines()]
for li in f3.readlines():
new_line = li.strip().split()[1][:-2]
for i in a:
if i in new_line:
f5.writelines(li)
阿神2017-04-17 17:47:22
실제 파일이 없기 때문에 100% 보장할 수는 없지만 코드에 대한 효율성 향상을 위한 몇 가지 제안 사항이 있습니다.
(개선된 코드에는 병렬 솔루션이 전혀 필요하지 않다는 것을 알게 될 것입니다)
먼저 큰 문제는 readlines()
입니다. 이 방법은 파일 객체의 모든 라인을 한 번에 읽습니다. 이는 수십만 라인과 수백만 개의 라인이 있기 때문에 효율성이 매우 낮습니다. 한 번에 다 읽어야 하는데 겁이 나요.
자세한 분석 및 토론은 파일에서 readlines()를 호출하지 않음
을 참조하세요.(기사 내 이 문단은 거의 경고라고 볼 수 있습니다)
StackOverflow와 같은 곳에 readlines 메서드에 대한 수백 가지 질문이 있으며 모든 경우에 대한 대답은 동일합니다.
"내 코드는 시작하기도 전에 시간이 오래 걸리지만 꽤 빠릅니다. 일단 시작하면 됩니다."
readline을 호출하기 때문입니다.
"단순한 루프임에도 불구하고 내 코드는 입력 크기에 있어 선형보다 더 나쁜 것 같습니다. "
readlines를 호출하고 있기 때문입니다.
"내 코드는 메모리가 부족해서 대용량 파일을 처리할 수 없습니다."
그건 당신이 호출하고 있기 때문입니다. 읽기라인.
결론은 readlines
이 사용된 곳은 모두 로 변경하는 것이 좋습니다.
예:
으아아아을 다음으로 변경해야 합니다.
으아아아직관적으로 효율성이 훨씬 좋아질 것입니다.
둘째, 키워드를 찾기 위해 목록을 사용했는데, 이 역시 상당히 비효율적입니다.
으아아아new_line
에 i
키워드가 있는지 확인하기 위해 전체 키워드 목록인 a
을 살펴보았는데, 일반적인 상황에서는 괜찮을 수 있지만, 수십만 개의 키워드를 비교하기는 어렵습니다. a
의 각 행을 방문하면 a
에 x개의 키워드가 있고 f3
에 y개의 행이 있고 각 행에 z개의 단어가 있다고 가정하면 시간이 많이 낭비됩니다. 파일의 줄 수에 따라 이 정도의 크기는 매우 놀랍습니다. x*y*z
이나 dictionary
처럼 해시를 사용하여 조회하는 컨테이너를 사용하는 것이 확실히 더 좋습니다. set
으아아아
잘 이해가 안 되네요.가 하위 문자열인 것 같은데, 이제 이 문자열을 사용하여 키워드를 비교하시겠습니까? new_line
에 관해서는, new_line
에 내가 인쇄하고 싶은 키워드가 여러 개 있다는 뜻이 아니라면, 인쇄 후에는 a
을 계속해서 반복해서는 안 될 것 같습니다. new_line
여러 번. 그렇지 않은 경우 line
를 추가하면 프로세스 속도가 빨라질 수도 있습니다. break
으아아아
틀렸다면 언제든지 말씀해 주세요. 직관적으로 문제는 병렬 처리를 사용하지 않고 해결되어야 합니다.黄舟2017-04-17 17:47:22
@dokelung의 답변에 따르면 약간의 수정만 거치면 기본적으로 내 요구 사항을 충족할 수 있습니다. 이 답변은 grep -f 4.txt 3.txt > 두 결과 파일의 차이점을 비교하는 것과 다소 다릅니다.
으아아아