Прочитайте первые N строк файла в python


У нас есть большой файл необработанных данных, который мы хотели бы обрезать до указанного размера. Я имею опыт работы в .net c#, однако хотел бы сделать это в python, чтобы упростить вещи и из интереса.

Как я могу получить первые N строк текстового файла в python? Будет ли используемая ОС иметь какое-либо влияние на реализацию?

13 99

13 ответов:

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

вот еще один способ

from itertools import islice
with open("datafile") as myfile:
    head = list(islice(myfile, N))
print head
N=10
f=open("file")
for i in range(N):
    line=f.next().strip()
    print line
f.close()

Если вы хотите быстро читать первые строки и вы не заботитесь о производительности, вы можете использовать .readlines() который возвращает объект списка, а затем нарезать список.

например, для первых 5 строк:

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

Примечание: весь файл читается так не самый лучший с точки зрения производительности но это проста в использовании, быстро писать и легко запомнить, так что если вы хотите просто проанализировать какой-то разовый расчет очень удобно

print firstNlines

нет определенного метода для чтения количества строк, предоставленных файловым объектом.

Я думаю самый простой способ будет следующим:

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

на основе gnibbler top voted answer (Nov 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)

то, что я делаю, это назвать n строк с помощью pandas. Я думаю, что производительность не самая лучшая, но например если N=1000:

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

два наиболее интуитивных способа сделать это было бы:

  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Инг весь файл в память, у вас есть много вариантов.

начиная с Python 2.6, вы можете воспользоваться более сложными функциями в базовом классе ввода-вывода. Таким образом, самый рейтинговый ответ выше может быть переписан как:

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

(вам не нужно беспокоиться о том, что ваш файл имеет менее N строк, так как не возникает исключения StopIteration.)

Если вы хотите что-то, что очевидно (без поиска эзотерических вещей в руководствах) работает без импорта и try/except и работает на справедливом диапазоне 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)

первые 5 строк, просто:

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

Если у вас действительно большой файл, и предполагая, что вы хотите, чтобы выход был массивом 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
#!/usr/bin/python

import subprocess

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

output, err = p.communicate()

print  output

этот метод работал для меня