Добавить 1D массив numpy в файл с новым элементом в новой строке

#python #arrays #numpy #file-io

#python #массивы #numpy #file-io

Вопрос:

У меня есть несколько массивов numpy, которые я генерирую итеративно. Я хочу сохранить каждый массив в файл. Затем я генерирую следующий массив и добавляю его в файл и так далее (если бы я сделал это за один раз, я бы использовал слишком много памяти). Как мне лучше всего это сделать? Есть ли способ сделать нас из функций numpy, таких как, например numpy.savetxt ? (Я не смог найти опцию добавления для этой функции.)

Мой текущий код:

 with open('paths.dat','w') as output:
    for i in range(len(hist[0])):
        amount = hist[0][i].astype(int)
        array = hist[1][i] * np.ones(amount)
        for value in array:
            output.write(str(value) 'n')
  

Комментарии:

1. Разве встроенная функция чтения / записи файлов Python не выполнит это?

2. Да, конечно, мне интересно, есть ли более эффективный простой способ сделать это. Сейчас я редактирую свой пост с этой целью.

3. @P-M Почему для вас так важно сохранить их в одном файле?

4. Другой инструментарий анализирует данные на следующем шаге и использует genfromtxt для воспроизведения списка (увы, сначала его нужно записать на диск). Я мог бы объединить массивы, сгенерированные, genfromtxt но они будут очень большими, поэтому, чем меньше я с ними работаю, тем лучше.

5. Ладно. Значит, вам не нужен доступ к данным во время их написания — только после того, как они будут полностью готовы?

Ответ №1:

Вы можете передать открытый файл (дескриптор) в savetxt

 with open('paths.dat','w') as output:
    for i in range(len(hist[0])):
        amount = hist[0][i].astype(int)
        myArray = hist[1][i] * np.ones(amount)
        np.savetxt(output, myArray, delimiter=',', fmt='f')
  

np.savetxt открывает файл, если задано имя, в противном случае он использовал файл.

Затем выполняет итерацию по строкам массива и записывает их

 for row in myArray:
    f.write(fmt % tuple(row))
  

где fmt находится строка, которую вы указываете, или строка, которая реплицируется в соответствии с количеством столбцов в вашем массиве.

Ответ №2:

Я бы рекомендовал использовать HDF5. Они очень быстры для ввода-вывода. Вот как вы записываете свои данные:

 import numpy as np
import tables

fname = 'myOutput.h5'
length = 100  # your data length
my_data_generator = xrange(length) # Your data comes here instead of the xrange

filters = tables.Filters(complib='blosc', complevel=5)  # you could change these
h5file = tables.open_file(fname, mode='w', title='yourTitle', filters=filters)
group = h5file.create_group(h5file.root, 'MyData', 'MyData')
x_atom = tables.Float32Atom()

x = h5file.create_carray(group, 'X', atom=x_atom, title='myTitle',
                         shape=(length,), filters=filters)

# this is a basic example.  It will be faster if you write it in larger chunks in your real code
# like x[start1:end1] = elements[start2:end2]
for element_i, element in enumerate(my_data_generator):
    x[element_i] = element
    h5file.flush()

h5file.close()
  

Для его чтения используйте:

 h5file = tables.open_file(fname, mode='r')
x = h5file.get_node('/MyData/X')
print x[:10]
  

Результат:

 marray([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9.], dtype=float32)