Ответ 1
Я представил этот ответ, потому что Кит, хотя и сжато, не закрывает файл явно
with open("log.txt") as infile:
for line in infile:
do_something_with(line)
Мне нужно прочитать большой файл по строкам. Предположим, что файл имеет более 5 ГБ, и мне нужно прочитать каждую строку, но, очевидно, я не хочу использовать readlines()
, потому что он создаст очень большой список в памяти.
Как будет работать код ниже для этого случая? Является ли xreadlines
само чтение по одному в память? Требуется ли выражение генератора?
f = (line for line in open("log.txt").xreadlines()) # how much is loaded in memory?
f.next()
Плюс, что я могу сделать, чтобы прочитать это в обратном порядке, так же как команда Linux tail
?
Я нашел:
http://code.google.com/p/pytailer/
и
"python head, tail и backward читается строками текстового файла"
Оба работали очень хорошо!
Я представил этот ответ, потому что Кит, хотя и сжато, не закрывает файл явно
with open("log.txt") as infile:
for line in infile:
do_something_with(line)
Все, что вам нужно сделать, это использовать файл-объект как итератор.
for line in open("log.txt"):
do_something_with(line)
Еще лучше использовать контекстный менеджер в последних версиях Python.
with open("log.txt") as fileobject:
for line in fileobject:
do_something_with(line)
Это также автоматически закроет файл.
Старый подход к школе:
fh = open(file_name, 'rt')
line = fh.readline()
while line:
# do stuff with line
line = fh.readline()
fh.close()
Вам лучше использовать итератор. Релевантно: http://docs.python.org/library/fileinput.html
Из документов:
import fileinput
for line in fileinput.input("filename"):
process(line)
Это позволит избежать копирования всего файла в память сразу.
Вот что вы делаете, если у вас нет новых строк в файле:
with open('large_text.txt') as f:
while True:
c = f.read(1024)
if not c:
break
print(c)
Попробуйте следующее:
with open('filename','r',buffering=100000) as f:
for line in f:
print line
Я не мог поверить, что это может быть так же просто, как это объяснил @john-la-rooy. Таким образом, я воссоздал команду cp
, используя строковое чтение и запись. Это CRAZY FAST.
#!/usr/bin/env python3.6
import sys
with open(sys.argv[2], 'w') as outfile:
with open(sys.argv[1]) as infile:
for line in infile:
outfile.write(line)
За последние 6 лет проект Blaze прошел долгий путь. Он имеет простой API, охватывающий полезное подмножество функций панд.
dask.dataframe заботится о внутреннем размещении, поддерживает много параллелизуемых операций и позволяет легко экспортировать фрагменты обратно в pandas для операций с памятью.
import dask.dataframe as dd
df = dd.read_csv('filename.csv')
df.head(10) # return first 10 rows
df.tail(10) # return last 10 rows
# iterate rows
for idx, row in df.iterrows():
...
# group by my_field and return mean
df.groupby(df.my_field).value.mean().compute()
# slice by column
df[df.my_field=='XYZ'].compute()
Как насчет этого? Разделите файл на куски, а затем прочитайте его по строкам, потому что когда вы читаете файл, ваша операционная система будет кэшировать следующую строку. Если вы читаете файл по строкам, вы не используете эффективное использование кэшированной информации.
Вместо этого разделите файл на куски и загрузите весь фрагмент в память, а затем выполните свою обработку.
def chunks(file,size=1024):
while 1:
startat=fh.tell()
print startat #file object current position from the start
fh.seek(size,1) #offset from current postion -->1
data=fh.readline()
yield startat,fh.tell()-startat #doesnt store whole list in memory
if not data:
break
if os.path.isfile(fname):
try:
fh=open(fname,'rb')
except IOError as e: #file --> permission denied
print "I/O error({0}): {1}".format(e.errno, e.strerror)
except Exception as e1: #handle other exceptions such as attribute errors
print "Unexpected error: {0}".format(e1)
for ele in chunks(fh):
fh.seek(ele[0])#startat
data=fh.read(ele[1])#endat
print data
Спасибо! Я недавно преобразовал в python 3 и был расстроен с помощью readlines (0) для чтения больших файлов. Это решило проблему. Но чтобы получить каждую строку, мне пришлось сделать еще пару шагов. Каждой строке предшествовал "b", который, я думаю, был в двоичном формате. Использование "decode (utf-8)" изменило его ascii.
Затем мне пришлось удалить "=\n" в середине каждой строки.
Затем я разделил строки на новой строке.
b_data=(fh.read(ele[1]))#endat This is one chunk of ascii data in binary format
a_data=((binascii.b2a_qp(b_data)).decode('utf-8')) #Data chunk in 'split' ascii format
data_chunk = (a_data.replace('=\n','').strip()) #Splitting characters removed
data_list = data_chunk.split('\n') #List containing lines in chunk
#print(data_list,'\n')
#time.sleep(1)
for j in range(len(data_list)): #iterate through data_list to get each item
i += 1
line_of_data = data_list[j]
print(line_of_data)
Вот код, начинающийся чуть выше "print data" в коде Arohi.
В этом другом вопросе я продемонстрировал метод параллельного байтового доступа с параллельным байтом:
Получение количества строк в текстовом файле без строк readline
Некоторые из уже предоставленных ответов хороши и кратки. Мне нравятся некоторые из них. Но это действительно зависит от того, что вы хотите делать с данными, содержащимися в файле. В моем случае я просто хотел подсчитать строки, как можно быстрее, в больших текстовых файлах. Мой код может быть изменен, чтобы делать и другие вещи, конечно, как и любой код.
Heres код для загрузки текстовых файлов любого размера без возникновения проблем с памятью. Он поддерживает файлы размером в гигабайт
https://gist.github.com/iyvinjose/e6c1cb2821abd5f01fd1b9065cbc759d
загрузите файл data_loading_utils.py и импортируйте его в свой код.
использование
import data_loading_utils.py.py
file_name = 'file_name.ext'
CHUNK_SIZE = 1000000
def process_lines(data, eof, file_name):
# check if end of file reached
if not eof:
# process data, data is one single line of the file
else:
# end of file reached
data_loading_utils.read_lines_from_file_as_data_chunks(file_name, chunk_size=CHUNK_SIZE, callback=self.process_lines)
Метод process_lines - это функция обратного вызова. Он будет вызываться для всех строк с данными параметров, представляющими одну строку файла за раз.
Вы можете настроить переменную CHUNK_SIZE в зависимости от конфигурации вашего оборудования.
Это может быть полезно, если вы хотите работать параллельно и читать только фрагменты данных, но сохраняйте их чистыми с помощью новых строк.
def readInChunks(fileObj, chunkSize=1024):
while True:
data = fileObj.read(chunkSize)
if not data:
break
while data[-1:] != '\n':
data+=fileObj.read(1)
yield data
f=open('filename','r').read()
f1=f.split('\n')
for i in range (len(f1)):
do_something_with(f1[i])
надеюсь, что это поможет.