Чтение и запись файлов
На этой странице рассматриваются распространённые приложения; для полного набора операций ввода-вывода см. Ввод и вывод.
Чтение текстовых и CSV файлов
Без пропущенных значений
Используйте numpy.loadtxt.
С пропущенными значениями
Используйте numpy.genfromtxt.
numpy.genfromtxt будет либо
- возвращать массированный массив, скрывая пропущенные значения (если
usemask=True), или - заполнять пропущенные значения заданным значением в
filling_values(по умолчаниюnp.nanдля float, -1 для int).
С разделителями, отличными от пробелов
>>> print(open("csv.txt").read())
1, 2, 3
4,, 6
7, 8, 9
Вывод массива с пропусками
>>> np.genfromtxt("csv.txt", delimiter=",", usemask=True)
masked_array(
data=[[1.0, 2.0, 3.0],
[4.0, --, 6.0],
[7.0, 8.0, 9.0]],
mask=[[False, False, False],
[False, True, False],
[False, False, False]],
fill_value=1e+20)
Вывод массива
>>> np.genfromtxt("csv.txt", delimiter=",")
array([[ 1., 2., 3.],
[ 4., nan, 6.],
[ 7., 8., 9.]])
Вывод массива, заданное значение заполнения
>>> np.genfromtxt("csv.txt", delimiter=",", dtype=np.int8, filling_values=99)
array([[ 1, 2, 3],
[ 4, 99, 6],
[ 7, 8, 9]], dtype=int8)
Разделенные пробелами
numpy.genfromtxt также может анализировать файлы данных, разделенные пробелами, с пропущенными значениями, если
-
Каждый столбец имеет фиксированную ширину: используйте ширину как аргумент
delimiter.# File with width=4. The data does not have to be justified (for example, # the 2 in row 1), the last column can be less than width (for example, the 6 # in row 2), and no delimiting character is required (for instance 8888 and 9 # in row 3) >>> f = open("fixedwidth.txt").read() # doctest: +SKIP >>> print(f) # doctest: +SKIP 1 2 3 44 6 7 88889 # Showing spaces as ^ >>> print(f.replace(" ","^")) # doctest: +SKIP 1^^^2^^^^^^3 44^^^^^^6 7^^^88889 >>> np.genfromtxt("fixedwidth.txt", delimiter=4) # doctest: +SKIP array([[1.000e+00, 2.000e+00, 3.000e+00], [4.400e+01, nan, 6.000e+00], [7.000e+00, 8.888e+03, 9.000e+00]]) -
Особое значение (например, «x») указывает пропущенное поле: используйте его как аргумент
missing_values.>>> print(open("nan.txt").read()) 1 2 3 44 x 6 7 8888 9 >>> np.genfromtxt("nan.txt", missing_values="x") array([[1.000e+00, 2.000e+00, 3.000e+00], [4.400e+01, nan, 6.000e+00], [7.000e+00, 8.888e+03, 9.000e+00]]) -
Вы хотите пропустить строки с пропущенными значениями: установите
invalid_raise=False.>>> print(open("skip.txt").read()) 1 2 3 44 6 7 888 9 >>> np.genfromtxt("skip.txt", invalid_raise=False) __main__:1: ConversionWarning: Some errors were detected ! Line #2 (got 2 columns instead of 3) array([[ 1., 2., 3.], [ 7., 888., 9.]]) -
Разделитель пробелов отличается от пробелов, обозначающих пропущенные данные. Например, если столбцы разделяются
\t, то пропущенные данные будут распознаны, если они состоят из одного или нескольких пробелов.>>> f = open("tabs.txt").read() >>> print(f) 1 2 3 44 6 7 888 9 # Tabs vs. spaces >>> print(f.replace("\t","^")) 1^2^3 44^ ^6 7^888^9 >>> np.genfromtxt("tabs.txt", delimiter="\t", missing_values=" +") array([[ 1., 2., 3.], [ 44., nan, 6.], [ 7., 888., 9.]])
Чтение файла в формате .npy или .npz
Варианты:
- Используйте
numpy.load. Он может читать файлы, созданные любым изnumpy.save,numpy.savezилиnumpy.savez_compressed. - Используйте отображение памяти. См.
numpy.lib.format.open_memmap.
Запись в файл для последующего чтения с помощью NumPy
Бинарный
Используйте numpy.save, или для хранения нескольких массивов numpy.savez или numpy.savez_compressed.
Для обеспечения безопасности и переносимости, установите allow_pickle=False , если тип данных не содержит Python-объектов, что требует сериализации с помощью pickle.
Массивы с пропусками can't currently be saved, также как и другие произвольные подклассы массивов.
Читаемый человеком
numpy.save и numpy.savez создают бинарные файлы. Для записи файла, читаемого человеком, используйте numpy.savetxt. Массив может быть только одномерным или двумерным, и нет `savetxtz` для нескольких файлов.
Крупные массивы
См. Запись или чтение больших массивов.
Чтение файла с произвольным бинарным форматом («бинарный блок»)
Используйте массив со структурированным типом данных.
Пример:
Заголовок файла .wav — это 44-байтовый блок, предшествующий data_size байтам фактических данных звука:
chunk_id "RIFF" chunk_size 4-byte unsigned little-endian integer format "WAVE" fmt_id "fmt " fmt_size 4-byte unsigned little-endian integer audio_fmt 2-byte unsigned little-endian integer num_channels 2-byte unsigned little-endian integer sample_rate 4-byte unsigned little-endian integer byte_rate 4-byte unsigned little-endian integer block_align 2-byte unsigned little-endian integer bits_per_sample 2-byte unsigned little-endian integer data_id "data" data_size 4-byte unsigned little-endian integer
Заголовок файла .wav как структурированный тип данных NumPy:
wav_header_dtype = np.dtype([
("chunk_id", (bytes, 4)), # flexible-sized scalar type, item size 4
("chunk_size", "<u4"), # little-endian unsigned 32-bit integer
("format", "S4"), # 4-byte string, alternate spelling of (bytes, 4)
("fmt_id", "S4"),
("fmt_size", "<u4"),
("audio_fmt", "<u2"), #
("num_channels", "<u2"), # .. more of the same ...
("sample_rate", "<u4"), #
("byte_rate", "<u4"),
("block_align", "<u2"),
("bits_per_sample", "<u2"),
("data_id", "S4"),
("data_size", "<u4"),
#
# the sound data itself cannot be represented here:
# it does not have a fixed size
])
header = np.fromfile(f, dtype=wave_header_dtype, count=1)[0]
Этот .wav пример для иллюстрации; для чтения файла .wav в реальной жизни используйте встроенный модуль Python wave.
(Приспособлено из Pauli Virtanen, Расширенный NumPy, лицензировано по CC BY 4.0.)
Запись или чтение больших массивов
Массивы, слишком большие для размещения в памяти, могут обрабатываться как обычные массивы в памяти с использованием отображения памяти.
-
Необработанные данные массива, записанные с помощью
numpy.ndarray.tofileилиnumpy.ndarray.tobytes, можно прочитать с помощьюnumpy.memmap:array = numpy.memmap("mydata/myarray.arr", mode="r", dtype=np.int16, shape=(1024, 1024)) -
Файлы, выведенные с помощью
numpy.save(т.е., используя формат numpy), можно прочитать с помощьюnumpy.loadс ключевым аргументомmmap_mode:large_array[some_slice] = np.load("path/to/small_array", mmap_mode="r")
Отображение памяти не обладает такими функциями, как разбиение данных и сжатие; более функциональные форматы и библиотеки, пригодные для использования с NumPy, включают:
- HDF5: h5py или PyTables.
- Zarr: здесь.
-
NetCDF:
scipy.io.netcdf_file.
Сравнение компромиссов между memmap, Zarr и HDF5 см. на pythonspeed.com.
Запись файлов для чтения другими (не NumPy) инструментами
Форматы для обмена данными с другими инструментами включают HDF5, Zarr и NetCDF (см. Запись или чтение больших массивов).
Запись или чтение файла JSON
Массивы NumPy не являются напрямую сериализуемыми в JSON.
Сохранение/восстановление с помощью файла pickle
Избегайте, когда это возможно; pickle не защищен от ошибочных или злонамеренно сконструированных данных.
Используйте numpy.save и numpy.load. Установите allow_pickle=False, если тип данных массива не включает Python-объектов, в противном случае требуется сериализация pickle.
Преобразование из pandas DataFrame в NumPy массив
См. pandas.DataFrame.to_numpy.
Сохранение/восстановление с помощью tofile и fromfile
В общем случае предпочитайте numpy.save и numpy.load.
numpy.ndarray.tofile и numpy.fromfile теряют информацию о порядке байтов и точности, поэтому они непригодны для чего-либо, кроме временного хранения.
© 2005–2021 NumPy Developers
Licensed under the 3-clause BSD License.
https://numpy.org/doc/1.20/user/how-to-io.html