Spec-Zone.ru › NumPy 1.20

Чтение и запись файлов

На этой странице рассматриваются распространённые приложения; для полного набора операций ввода-вывода см. Ввод и вывод.

Чтение текстовых и 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API