2009-11-20 2 views
84

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

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

Спасибо :)

ответ

135
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 
+1

Спасибо, это очень полезно. Какая разница между двумя? (с точки зрения производительности, требуемых библиотек, совместимости и т. д.)? – Russell

+1

Я ожидаю, что производительность будет одинаковой, возможно, первая будет немного быстрее. Но первый не будет работать, если файл не имеет не менее N строк. Лучше всего измерить производительность по сравнению с некоторыми типичными данными, с которыми вы будете их использовать. –

+1

Оператор with работает на Python 2.6 и требует дополнительного оператора импорта на 2.5. Для версии 2.4 или более ранней версии вам потребуется переписать код с помощью try ... except block. Стилистически, я предпочитаю первый вариант, хотя, как уже упоминалось, второй более надежный для коротких файлов. – Alasdair

5

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

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

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

Это то, что я на самом деле намеревался. Хотя, хотя я добавляю каждую строку в список. Спасибо. – artdanil

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) 
15
N=10 
f=open("file") 
for i in range(N): 
    line=f.next().strip() 
    print line 
f.close() 
+14

Я сжимаю всякий раз, когда вижу 'f = open (" file ")' без обработки исключений, чтобы закрыть файл. Питоновский способ обработки файлов - с помощью диспетчера контекста, то есть с помощью оператора with. Это описано в [исходном учебнике Python ввода] (http://docs.python.org/2/tutorial/inputoutput.html#methods-of-file-objects). «Эффективная практика заключается в использовании ключевого слова« с »при работе с файловыми объектами. Это имеет то преимущество, что файл правильно закрыт после завершения его набора, даже если возникло исключение на пути». ' –

3

на основе gnibbler топ проголосовали ответ (20 Nov '09 в 0:27): этот класс добавить головку() и хвост() для файл ob ект.

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) 
2

наиболее удобный способ сам по себе:

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

Решение основано на List Comprehension Функция Open() поддерживает интерфейс итерации. Элемент перечисления() охватывает open() и возвращает кортежи (индекс, элемент), затем мы проверяем, что мы находимся внутри принятого диапазона (если i < LINE_COUNT), а затем просто распечатаем результат.

Наслаждайтесь Python. ;)

3

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

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

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

+23

Согласно [docs ] (http://docs.python.org/2/library/stdtypes.html#file.readlines) N - это число _bytes_ для чтения, ** не ** количество _lines_. –

+2

N - количество байтов! – qed

+4

Ничего себе. Расскажите о бедных именах. Имя функции упоминает 'lines', но аргумент ссылается на' bytes'. – ArtOfWarfare

7

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

E.g.в течение первых 5 строк:

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

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

print firstNlines 
+2

Верхний ответ, вероятно, более эффективен, но этот работает как прелесть для небольших файлов. –

+1

Обратите внимание, что это фактически сначала считывает весь файл в список (myfile.readlines()), а затем соединяет первые 5 строк. – AbdealiJK

0

Если у вас есть очень большой файл, и Ассу ming вы хотите, чтобы выход был массивом 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 
2

Для первых 5 строк, просто сделать:

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

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

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

Лучше было бы использовать параметр «nrows», который может быть установлен на 1000, а весь файл не загружен. http://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_csv.html В общем, у панд есть эта и другие методы экономии памяти для больших файлов. – philshem

+0

Да, вы правы. Я просто исправлю это. Извините за ошибку. –

+1

Вы также можете добавить 'sep' для определения разделителя столбцов (который не должен происходить в не-CSV-файле) – philshem

0
#!/usr/bin/python 

import subprocess 

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

output, err = p.communicate() 

print output 

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

0

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

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

Смежные вопросы