파이썬에서 파일의 첫 N 줄을 읽습니다.


150

지정된 크기로 자르려는 큰 원시 데이터 파일이 있습니다. .net c #에서 경험이 있지만 파이썬 에서이 작업을 단순화하고 관심을 끌기를 원합니다.

파이썬에서 텍스트 파일의 첫 N 줄을 얻는 방법은 무엇입니까? 사용중인 OS가 구현에 영향을 줍니까?


명령 줄 인수로 n을 줄 수
있습니까

답변:


240

파이썬 2

with open("datafile") as myfile:
    head = [next(myfile) for x in xrange(N)]
print head

파이썬 3

with open("datafile") as myfile:
    head = [next(myfile) for x in range(N)]
print(head)

다른 방법이 있습니다 (Python 2 & 3)

from itertools import islice
with open("datafile") as myfile:
    head = list(islice(myfile, N))
print head

1
고마워, 그것은 실제로 매우 도움이됩니다. 둘의 차이점은 무엇입니까? (성능, 필수 라이브러리, 호환성 등)면에서?
Russell

1
나는 성능이 비슷할 것으로 기대합니다. 첫 번째는 약간 더 빠를 것입니다. 그러나 파일에 N 줄 이상이 없으면 첫 번째 파일이 작동하지 않습니다. 사용할 일반적인 데이터와 비교하여 성능을 측정하는 것이 가장 좋습니다.
John La Rooy

1
with 문은 Python 2.6에서 작동하며 2.5에서 추가 import 문이 필요합니다. 2.4 이하 버전에서는 try ... except 블록으로 코드를 다시 작성해야합니다. 앞서 언급했듯이 두 번째 파일은 짧은 파일에 대해 더 강력하지만, 독창적으로 첫 번째 옵션을 선호합니다.
Alasdair

1
islice는 아마도 C로 구현 될 때 더 빠를 것입니다.
Alice Purcell

22
파일에 N 줄 미만인 경우 처리해야하는 StopIteration 예외가 발생합니다
Ilian Iliev

19
N = 10
with open("file.txt", "a") as file:  # the a opens it in append mode
    for i in range(N):
        line = next(file).strip()
        print(line)

23
f = open("file")예외 처리없이 파일을 닫을 때마다 울었 습니다. 파일을 처리하는 파이썬적인 방법은 컨텍스트 관리자를 사용하는 것입니다. 이것은 입력 출력 Python 튜토리얼 에서 다룹니다 . "It is good practice to use the with keyword when dealing with file objects. This has the advantage that the file is properly closed after its suite finishes, even if an exception is raised on the way."
Mark Mikofski

1
추가 모드에서 파일을 여는 이유는 무엇입니까?
AMC

13

첫 줄을 빠르게 읽고 성능에 신경 쓰지 않으려면 .readlines()반환 목록 객체를 사용 하고 목록을 슬라이스하면됩니다.

예를 들어 처음 5 줄의 경우 :

with open("pathofmyfileandfileandname") as myfile:
    firstNlines=myfile.readlines()[0:5] #put here the interval you want

참고 : 전체 파일을 읽었으므로 성능 관점에서 최고는 아니지만 사용하기 쉽고 빠르며 기억하기 쉽기 때문에 일회성 계산을 수행하려는 경우 매우 편리합니다

print firstNlines

다른 답변과 비교하여 한 가지 장점은 라인 범위를 쉽게 선택할 수 있다는 것입니다. 예를 들어 처음 10 줄을 건너 뛰 [10:30]거나 마지막 10 줄을 건너 뛰 [:-10]거나 짝수 줄만 사용할 수도 있습니다 [::2].


2
가장 좋은 대답은 아마 더 효율적이지만 작은 파일의 매력처럼 작동합니다.
T.Chmelevskij

2
실제로 전체 파일을 먼저 목록 (myfile.readlines ())으로 읽은 다음 파일의 처음 5 줄을 연결합니다.
AbdealiJK

2
이것은 피해야합니다.
anilbey

1
나는 이것을 사용할 이유가 없다. 훨씬 더 효율적인 솔루션보다 간단하지는 않다.
AMC

@AMC는 피드백에 감사드립니다. 첫 번째 줄을 빨리 살펴 봐야 할 때 콘솔을 사용하여 데이터를 탐색하면 코드 작성 시간을 절약 할 수 있습니다.
GM

9

내가하는 일은을 사용하여 N 줄을 호출하는 것 pandas입니다. 나는 성능이 최고가 아니라고 생각하지만, 예를 들어 N=1000:

import pandas as pd
yourfile = pd.read('path/to/your/file.csv',nrows=1000)

3
nrows옵션 을 사용하는 것이 좋습니다.이 옵션은 1000으로 설정 될 수 있으며 전체 파일이로드되지 않습니다. pandas.pydata.org/pandas-docs/stable/generated/… 일반적으로 pandas는 큰 파일을위한 이것과 다른 메모리 절약 기술을 가지고 있습니다.
philshem

네, 맞아요. 방금 수정했습니다. 실수해서 죄송합니다.
Cro-Magnon

1
sepcsv가 아닌 파일에서는 발생하지 않아야하는 열 구분 기호를 정의 하기 위해 추가 할 수도 있습니다.
philshem

1
@ Cro-Magnon pandas.read()설명서 에서 기능을 찾을 수 없습니다 . 주제에 대한 정보가 있습니까?
AMC

6

파일 객체에 의해 노출 된 줄 수를 읽는 특정 방법은 없습니다.

가장 쉬운 방법은 다음과 같습니다.

lines =[]
with open(file_name) as f:
    lines.extend(f.readline() for i in xrange(N))

이것은 내가 실제로 의도 한 것입니다. 그래도 목록에 각 줄을 추가합니다. 감사합니다.
artdanil 2009

4

gnibbler 최고 투표 답변 (11 : 20 '09 at 0:27)을 기반으로 :이 클래스는 파일 객체에 head () 및 tail () 메서드를 추가합니다.

class File(file):
    def head(self, lines_2find=1):
        self.seek(0)                            #Rewind file
        return [self.next() for x in xrange(lines_2find)]

    def tail(self, lines_2find=1):  
        self.seek(0, 2)                         #go to end of file
        bytes_in_file = self.tell()             
        lines_found, total_bytes_scanned = 0, 0
        while (lines_2find+1 > lines_found and
               bytes_in_file > total_bytes_scanned): 
            byte_block = min(1024, bytes_in_file-total_bytes_scanned)
            self.seek(-(byte_block+total_bytes_scanned), 2)
            total_bytes_scanned += byte_block
            lines_found += self.read(1024).count('\n')
        self.seek(-total_bytes_scanned, 2)
        line_list = list(self.readlines())
        return line_list[-lines_2find:]

용법:

f = File('path/to/file', 'r')
f.head(3)
f.tail(3)

4

이를 수행하는 가장 직관적 인 두 가지 방법은 다음과 같습니다.

  1. 파일 한 줄 한 줄에 반복하고, break이후 N라인.

  2. next()메소드 N시간을 사용하여 파일을 한 줄씩 반복하십시오 . (이것은 본질적으로 최고의 답변이하는 것과 다른 구문입니다.)

코드는 다음과 같습니다.

# Method 1:
with open("fileName", "r") as f:
    counter = 0
    for line in f:
        print line
        counter += 1
        if counter == N: break

# Method 2:
with open("fileName", "r") as f:
    for i in xrange(N):
        line = f.next()
        print line

결론은 당신이 사용하지 않는 한,이다 readlines()또는 enumerate메모리에 전체 파일을 보내고, 당신은 많은 옵션을 가지고있다.


3

가장 편한 방법 :

LINE_COUNT = 3
print [s for (i, s) in enumerate(open('test.txt')) if i < LINE_COUNT]

List Comprehension 기반 솔루션 open () 함수는 반복 인터페이스를 지원합니다. enumerate ()는 open () 및 반환 튜플 (인덱스, 항목)을 다루고 허용 범위 (i <LINE_COUNT 인 경우) 내에 있는지 확인한 다음 결과를 인쇄합니다.

파이썬을 즐기십시오. ;)


이것은 약간 더 복잡한 대안으로 보입니다 [next(file) for _ in range(LINE_COUNT)].
AMC

3

처음 5 줄의 경우 다음을 수행하십시오.

N=5
with open("data_file", "r") as file:
    for i in range(N):
       print file.next()

2

명백히 (매뉴얼에서 난해한 것들을 찾지 않고) 무언가를 가져 오기없이 시도하고 제외하고 시도하고 공정한 범위의 Python 2.x 버전 (2.2 ~ 2.6)에서 작동하는 경우 :

def headn(file_name, n):
    """Like *x head -N command"""
    result = []
    nlines = 0
    assert n >= 1
    for line in open(file_name):
        result.append(line)
        nlines += 1
        if nlines >= n:
            break
    return result

if __name__ == "__main__":
    import sys
    rval = headn(sys.argv[1], int(sys.argv[2]))
    print rval
    print len(rval)

2

정말 큰 파일을 가지고 있고 출력을 numpy 배열로 가정하면 np.genfromtxt를 사용하면 컴퓨터가 정지됩니다. 이것은 내 경험에서 훨씬 낫습니다.

def load_big_file(fname,maxrows):
'''only works for well-formed text file of space-separated doubles'''

rows = []  # unknown number of lines, so use list

with open(fname) as f:
    j=0        
    for line in f:
        if j==maxrows:
            break
        else:
            line = [float(s) for s in line.split()]
            rows.append(np.array(line, dtype = np.double))
            j+=1
return np.vstack(rows)  # convert list of vectors to array

정말 큰 파일을 가지고 있고 출력을 numpy 배열로 원한다고 가정하면 매우 독특한 제한 사항이므로 대안에 비해 이것에 대한 이점을 실제로 볼 수는 없습니다.
AMC

1

Python 2.6부터 IO 기본 클래스에서보다 정교한 함수를 활용할 수 있습니다. 따라서 위의 최고 등급의 답변은 다음과 같이 다시 작성할 수 있습니다.

    with open("datafile") as myfile:
       head = myfile.readlines(N)
    print head

StopIteration 예외가 발생하지 않기 때문에 N 줄 미만의 파일에 대해 걱정할 필요가 없습니다.


25
문서 에 따르면 N은 수가 아니라 읽을 바이트 수입니다 .
Mark Mikofski

4
N은 바이트 수입니다!
qed

5
와. 나쁜 이름에 대해 이야기하십시오. 함수 이름은 언급 lines하지만 인수는을 나타냅니다 bytes.
ArtOfWarfare

0

이것은 나를 위해 일했다

f = open("history_export.csv", "r")
line= 5
for x in range(line):
    a = f.readline()
    print(a)

컨텍스트 관리자를 사용하지 않는 이유는 무엇입니까? 어쨌든 이것이 기존의 많은 답변에서 어떻게 개선되는지 알 수 없습니다.
AMC

0

이것은 Python 2 & 3에서 작동합니다.

from itertools import islice

with open('/tmp/filename.txt') as inf:
    for line in islice(inf, N, N+M):
        print(line)

이것은 10 년 전의 최고 답변 과 거의 동일합니다 .
AMC

0

fname = input("Enter file name: ")
num_lines = 0

with open(fname, 'r') as f: #lines count
    for line in f:
        num_lines += 1

num_lines_input = int (input("Enter line numbers: "))

if num_lines_input <= num_lines:
    f = open(fname, "r")
    for x in range(num_lines_input):
        a = f.readline()
        print(a)

else:
    f = open(fname, "r")
    for x in range(num_lines_input):
        a = f.readline()
        print(a)
        print("Don't have", num_lines_input, " lines print as much as you can")


print("Total lines in the text",num_lines)

-1
#!/usr/bin/python

import subprocess

p = subprocess.Popen(["tail", "-n 3", "passlist"], stdout=subprocess.PIPE)

output, err = p.communicate()

print  output

이 방법은 나를 위해 일했다


그러나 이것은 실제로 파이썬 솔루션이 아닙니다.
AMC

나는 당신의 대답에 쓰여진 것을 이해하지 못합니다. 설명을 추가하십시오.
Alexei Marinichenko
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.