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

Эта страница охватывает распространенные применения; для полного набора подпрограмм ввода-вывода см. Вход и выход.

Чтение текста и CSV файлы#

Без пропущенных значений#

Используйте numpy.loadtxt.

С пропущенными значениями#

Используйте numpy.genfromtxt.

numpy.genfromtxt будет либо

  • возвращает маскированный массив маскирование пропущенных значений (если usemask=True), или

  • заполнить пропущенное значение со значением, указанным в filling_values (по умолчанию np.nan для float, -1 для int).

С разделителями, не являющимися пробелами#

>>> with open("csv.txt", "r") as f:
...     print(f.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 также может анализировать файлы данных с разделителями-пробелами, которые имеют пропущенные значения, если

  • Каждое поле имеет фиксированную ширину: Использовать ширину как разделитель аргумент.:

    # 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)
    
    >>> with open("fixedwidth.txt", "r") as f:
    ...    data = (f.read())
    >>> print(data)
    1   2      3
    44      6
    7   88889
    
    # Showing spaces as ^
    >>> print(data.replace(" ","^"))
    1^^^2^^^^^^3
    44^^^^^^6
    7^^^88889
    
    >>> np.genfromtxt("fixedwidth.txt", delimiter=4)
    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 аргумент.

    >>> with open("nan.txt", "r") as f:
    ...     print(f.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.

    >>> with open("skip.txt", "r") as f:
    ...     print(f.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, тогда пропущенные данные будут распознаны, если они состоят из одного или нескольких пробелов.:

    >>> with open("tabs.txt", "r") as f:
    ...    data = (f.read())
    >>> print(data)
    1       2       3
    44              6
    7       888     9
    
    # Tabs vs. spaces
    >>> print(data.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#

Бинарный#

Используйте numpy.saveили для хранения нескольких массивов numpy.savez или numpy.savez_compressed.

Для безопасность и переносимость, установите allow_pickle=False если только тип данных не содержит объектов Python, что требует сериализации.

Маскированные массивы can't currently be saved, ни другие произвольные подклассы массивов.

Человекочитаемый#

numpy.save и numpy.savez создавать двоичные файлы. Чтобы записать человекочитаемый файл, используйте numpy.savetxt. Массив может быть только 1- или 2-мерным, и нет savetxtz для нескольких файлов.

Большие массивы#

См. Запись или чтение больших массивов.

Чтение бинарного файла произвольного формата («бинарный блоб»)#

Используйте структурированный массив.

Пример:

The .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

The .wav заголовок файла как структурированный dtype NumPy:

wav_header_dtype = np.dtype([
    ("chunk_id", (bytes, 4)), # flexible-sized scalar type, item size 4
    ("chunk_size", "),    # little-endian unsigned 32-bit integer
    ("format", "S4"),         # 4-byte string, alternate spelling of (bytes, 4)
    ("fmt_id", "S4"),
    ("fmt_size", "),
    ("audio_fmt", "),     #
    ("num_channels", "),  # .. more of the same ...
    ("sample_rate", "),   #
    ("byte_rate", "),
    ("block_align", "),
    ("bits_per_sample", "),
    ("data_id", "S4"),
    ("data_size", "),
    #
    # 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, включают:

Для сравнения компромиссов между memmap, Zarr и HDF5 см. pythonspeed.com.

Запись файлов для чтения другими (не NumPy) инструментами#

Форматы для обмен данными с другими инструментами включают HDF5, Zarr и NetCDF (см. Запись или чтение больших массивов).

Записать или прочитать файл JSON#

Массивы NumPy и большинство скаляров NumPy являются не напрямую Сериализуемый в JSON. Вместо этого используйте пользовательский json.JSONEncoder для типов NumPy, которые можно найти с помощью вашей любимой поисковой системы.

Сохранение/восстановление с использованием файла pickle#

Избегайте, когда возможно; сериализует не защищены от ошибочных или злонамеренно сконструированных данных.

Используйте numpy.save и numpy.load. Установить allow_pickle=False, если только dtype массива не включает объекты Python, в этом случае требуется сериализация.

numpy.load и pickle подмодуль также поддерживает распаковку файлов, созданных с NumPy 1.26.

Преобразование из pandas DataFrame в массив NumPy#

См. pandas.Series.to_numpy.

Сохранить/восстановить с помощью tofile и fromfile#

В общем случае предпочтительнее numpy.save и numpy.load.

numpy.ndarray.tofile и numpy.fromfile теряют информацию о порядке байтов и точности и поэтому непригодны ни для чего, кроме временного хранения.