2012-06-10 5 views
1

У меня есть файл test.txt, который имеет массив:получить конкретное содержание из файла питона

array = [3,5,6,7,9,6,4,3,2,1,3,4,5,6,7,8,5,3,3,44,5,6,6,7] 

Теперь то, что я хочу сделать, это получить содержимое массива и выполнить некоторые вычисления с массивом. Но проблема в том, что когда я делаю open("test.txt"), он выводит содержимое как строку. На самом деле массив очень большой, и если я сделаю цикл, он может оказаться неэффективным. Есть ли способ получить контент без разделения ,? Любые новые идеи?

+2

Почему бы просто не сделать файл .py с данными? –

ответ

5

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

1,2,3,4,5 

Тогда вы могли бы чтение/запись с csv модуля или функции Numpy упомянутых выше. Существует много документации о том, как эффективно читать данные csv. После того, как вы были ваши данные чтения CSV объект настройки, данные могут быть сохранены с чем-то вроде:

data = [ map(float, row) for row in csvreader] 
9

Я рекомендую вам сохранить файл как json вместо этого и прочитать его с помощью модуля json. Либо это, либо сделать его .py-файлом, и импортировать его как python. Файл .txt, похожий на назначение python, является нечетным.

5

Если вы хотите сохранить питон, как выражение в файл, хранить только выражение (т.е. без array =) и разобрать его с помощью ast.literal_eval().

Однако рассмотрите возможность использования другого формата, такого как JSON. В зависимости от расчетов вы также можете рассмотреть возможность использования формата, в котором вам не нужно одновременно загружать все данные в память.

2

Должен ли массив быть сохранен как строка? Не могли бы вы использовать файл pickle и сохранить его как список Python?

Если нет, можете ли вы попробовать ленивую оценку? Может быть, только обрабатывать разделы массива по мере необходимости.

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

1

Вы можете написать парсер. Они очень просты. И гораздо быстрее, чем регулярные выражения, пожалуйста, не делайте этого. Не то, чтобы кто-то это предлагал.

# open up the file (r = read-only, b = binary) 
stream = open("file_full_of_numbers.txt", "rb") 
prefix = '' # end of the last chunk 
full_number_list = [] 

# get a chunk of the file at a time 
while True: 
    # just a small 1k chunk 
    buffer = stream.read(1024) 
    # no more data is left in the file 
    if '' == buffer: 
     break 
    # delemit this chunk of data by a comma 
    split_result = buffer.split(",") 
    # append the end of the last chunk to the first number 
    split_result[0] = prefix + split_result[0] 
    # save the end of the buffer (a partial number perhaps) for the next loop 
    prefix = split_result[-1] 
    # only work with full results, so skip the last one 
    numbers = split_result[0:-1] 
    # do something with the numbers we got (like save it into a full list) 
    full_number_list += numbers 

# now full_number_list contains all the numbers in text format 

Вам также придется добавить некоторую логику, чтобы использовать префикс, когда буфер пуст. Но я оставлю этот код вам.

2

Вы также можете использовать numpy для загрузки данных из файла с помощью numpy.genfromtxt или numpy.loadtxt. Оба довольно быстрые, и оба имеют возможность выполнять переработку при загрузке. Если массив уже загружен, вы можете использовать numpy для преобразования его в массив float, и это очень быстро.

import numpy as np 
a = np.array(["1", "2", "3", "4"]) 
a = a.astype(np.float) 
1

OK, поэтому следующие методы опасны. Поскольку они используются для атаки систем, введя в них код, они использовали их на свой страх и риск.
array = eval(open("test.txt", 'r').read().strip('array = '))
execfile('test.txt') # this is the fastest but most dangerous.

более безопасные методы.

import ast 
array = ast.literal_eval(open("test.txt", 'r').read().strip('array = ')). 
    ... 
array = [float(value) for value in open('test.txt', 'r').read().strip('array = [').strip('\n]').split(',')] 

eassiest способ сериализации объектов питона, так что вы можете загрузить их позже, чтобы использовать рассол. Предполагая, что вы не хотите читаемого человеком формата, так как это добавляет основную голову, либо мудрый, csv быстр, а json является гибким.

import pickle 
import random 
array = random.sample(range(10**3), 20) 
pickle.dump(array, open('test.obj', 'wb')) 

loaded_array = pickle.load(open('test.obj', 'rb')) 
assert array == loaded_array 

рассол имеет некоторые накладные расходы, и если вам нужно сериализовать большие объекты можно указать степень сжатия по умолчанию равно 0 без сжатия, вы можете установить его в pickle.HIGHEST_PROTOCOL pickle.dump(array, open('test.obj', 'wb'), pickle.HIGHEST_PROTOCOL)

If вы работаете с большими численными или научными наборами данных, затем используйте numpy.tofile/numpy.fromfile или scipy.io.savemat/scipy.io.loadmat, у них мало накладных расходов, но опять же, только если вы уже используете numpy/scipy.

удачи.

+0

ast.literal_eval() было бы лучше и безопасно использовать –

+0

Да, но в сообществе python мы всегда предполагаем, что мы все соглашаемся с взрослыми, и мы знаем, что делаем. К сожалению, это редко бывает. –

+0

Я удалил -1 и добавил +1 –