Рубрики
Без рубрики

Почему вы должны чаще использовать файл .npy…

Наука о данных нуждается в быстром вычислении и преобразовании данных. Собственные объекты NumPy в Python обеспечивают это преимущество перед обычными объектами программирования. Он работает для такой простой задачи, как чтение числового набора данных из файла на диске. Мы демонстрируем это в нескольких простых строках кода.

Автор оригинала: Tirthajyoti Sarkar.

Наука о данных нуждается в быстром вычислении и преобразовании данных. Собственные объекты NumPy в Python обеспечивают это преимущество перед обычными объектами программирования. Он работает для такой простой задачи, как чтение числового набора данных из файла на диске. Мы демонстрируем это в нескольких простых строках кода.

Вступление

Numpy, сокращенно от Numerical Python , является фундаментальным пакетом, необходимым для высокопроизводительных научных вычислений и анализа данных в экосистеме Python. Это основа, на которой построены почти все инструменты более высокого уровня, такие как Pandas и scikit-learn . TensorFlow использует массивы NumPy в качестве фундаментального строительного блока, поверх которого они построили свои тензорные объекты и graphflow для задач глубокого обучения (что делает интенсивным использование операций линейной алгебры над длинным списком/вектором/матрицей чисел).

Было написано много статей, демонстрирующих преимущество массива Numpy перед простыми списками ванильного Python. Вы часто будете сталкиваться с этим утверждением в сообществе data science, machine learning и Python, что Numpy намного быстрее из-за своей векторизованной реализации и из-за того, что многие из его основных подпрограмм написаны на C (на основе CPython framework ). И это действительно так ( эта статья-прекрасная демонстрация различных вариантов работы с Numpy, даже написания голых C-подпрограмм с помощью Numpy API). Массивы Numpy-это плотно упакованные массивы однородного типа. Списки Python, напротив, представляют собой массивы указателей на объекты, даже если все они имеют один и тот же тип. Вы получаете преимущества локальности отсчета .

В одной из моих высоко цитируемых статей о платформе Towards Data Science platform я продемонстрировал преимущество использования векторизованных операций Numpy перед традиционными конструкциями программирования , такими как for-loop .

Однако менее ценен тот факт, что когда речь заходит о повторном чтении одних и тех же данных из локального (или сетевого) дискового хранилища, Numpy предлагает другой драгоценный камень, называемый форматом файла .npy . Этот формат файла делает невероятно быстрое повышение скорости чтения по сравнению с чтением из обычного текста или CSV-файлов.

Загвоздка в том, что, конечно, вы должны прочитать данные традиционным способом в первый раз и создать в памяти объект NumPy ndarray . Но если вы используете один и тот же CSV-файл для повторного чтения одного и того же набора числовых данных, то имеет смысл хранить ndarray в файле npy вместо того, чтобы снова и снова читать его из исходного CSV.

Что это за файл .NPY?

Это стандартный двоичный формат файла для сохранения одного произвольного массива NumPy на диске. Формат хранит всю информацию о форме и типе данных, необходимую для правильной реконструкции массива даже на другой машине с другой архитектурой. Формат разработан таким образом, чтобы быть максимально простым при достижении своих ограниченных целей. Реализация предназначена для чистого Python и распространяется как часть основного пакета numpy.

Формат ДОЛЖЕН быть в состоянии:

  • Представляют все массивы NumPy, включая вложенные массивы записей и массивы объектов.
  • Представьте данные в их собственной двоичной форме.
  • Содержаться в одном файле.
  • Храните всю необходимую информацию для восстановления массива, включая форму и тип данных, на машине другой архитектуры. Должны поддерживаться как литтл-эндианские, так и биг-эндианские массивы, и файл с литтл-эндианскими числами даст литтл-эндианский массив на любой машине, считывающей файл. Типы должны быть описаны в терминах их фактических размеров. Например, если машина с 64-битным C “long int” записывает массив с “long ints”, то считывающая машина с 32-битным C “long ints” выдаст массив с 64-битными целыми числами.
  • Будьте реверсивно спроектированы. Наборы данных часто живут дольше, чем программы, которые их создали. Компетентный разработчик должен быть в состоянии создать решение на своем предпочтительном языке программирования для чтения большинства файлов NPY, которые ему были даны без большой документации.
  • Разрешить отображение данных в памяти.

Демонстрация с использованием простого кода

Как всегда, вы можете скачать boilerplate code Notebook из моего репозитория Github . Здесь я показываю основной фрагмент кода.

Во-первых, обычный метод чтения CSV-файла в списке и преобразования его в ndarray.

import numpy as np
import time

# 1 million samples
n_samples=1000000

# Write random floating point numbers as string on a local CSV file
with open('fdata.txt', 'w') as fdata:
    for _ in range(n_samples):
        fdata.write(str(10*np.random.random())+',')

# Read the CSV in a list, convert to ndarray (reshape just for fun) and time it
t1=time.time()
with open('fdata.txt','r') as fdata:
    datastr=fdata.read()
lst = datastr.split(',')
lst.pop()
array_lst=np.array(lst,dtype=float).reshape(1000,1000)
t2=time.time()

print(array_lst)
print('\nShape: ',array_lst.shape)
print(f"Time took to read: {t2-t1} seconds.")

>> [[0.32614787 6.84798256 2.59321025 ... 5.02387324 1.04806225 2.80646522]
 [0.42535168 3.77882315 0.91426996 ... 8.43664343 5.50435042 1.17847223]
 [1.79458482 5.82172793 5.29433626 ... 3.10556071 2.90960252 7.8021901]
 ...
 [3.04453929 1.0270109 8.04185826 ... 2.21814825 3.56490017 3.72934854]
 [7.11767505 7.59239626 5.60733328 ... 8.33572855 3.29231441 8.67716649]
 [4.2606672 0.08492747 1.40436949 ... 5.6204355 4.47407948 9.50940101]]

>> Shape: (1000, 1000)
>> Time took to read: 1.018733024597168 seconds.

Так что это было первое чтение, которое вы должны сделать в любом случае. Но если вы , вероятно, будете использовать один и тот же набор данных еще много раз , то после завершения процесса обработки данных не забудьте сохранить объект ndarray в формате .npy |/.

np.save(‘f numpy.npy’, array_lst)

Потому что если вы это сделаете, то в следующий раз чтение с диска будет очень быстрым!

t1=time.time()
array_reloaded = np.load('fnumpy.npy')
t2=time.time()

print(array_reloaded)
print('\nShape: ',array_reloaded.shape)
print(f"Time took to load: {t2-t1} seconds.")

>> [[0.32614787 6.84798256 2.59321025 ... 5.02387324 1.04806225 2.80646522]
 [0.42535168 3.77882315 0.91426996 ... 8.43664343 5.50435042 1.17847223]
 [1.79458482 5.82172793 5.29433626 ... 3.10556071 2.90960252 7.8021901]
 ...
 [3.04453929 1.0270109 8.04185826 ... 2.21814825 3.56490017 3.72934854]
 [7.11767505 7.59239626 5.60733328 ... 8.33572855 3.29231441 8.67716649]
 [4.2606672 0.08492747 1.40436949 ... 5.6204355 4.47407948 9.50940101]]

>> Shape: (1000, 1000)
>> Time took to load: 0.009010076522827148 seconds.

Не имеет значения, хотите ли вы загрузить данные в какой-то другой форме,

t1=time.time()
array_reloaded = np.load('fnumpy.npy').reshape(10000,100)
t2=time.time()

print(array_reloaded)
print('\nShape: ',array_reloaded.shape)
print(f"Time took to load: {t2-t1} seconds.")

>> [[0.32614787 6.84798256 2.59321025 ... 3.01180325 2.39479796 0.72345778]
 [3.69505384 4.53401889 8.36879084 ... 9.9009631 7.33501957 2.50186053]
 [4.35664074 4.07578682 1.71320519 ... 8.33236349 7.2902005 5.27535724]
 ...
 [1.11051629 5.43382324 3.86440843 ... 4.38217095 0.23810232 1.27995629]
 [2.56255361 7.8052843 6.67015391 ... 3.02916997 4.76569949 0.95855667]
 [6.06043577 5.8964256 4.57181929 ... 5.6204355 4.47407948 9.50940101]]

>> Shape: (10000, 100)
>> Time took to load: 0.010006189346313477 seconds.

Оказывается, что, по крайней мере, в этом конкретном случае размер файла на диске также меньше для формата .npy.

Резюме

В этой статье мы продемонстрируем полезность использования собственного формата файла NumPy .npy поверх CSV для чтения большого набора числовых данных. Это может быть полезным трюком, если один и тот же файл данных CSV нужно читать много раз.

Подробнее об этом формате файла читайте здесь .

Если у вас есть какие-либо вопросы или идеи, которыми вы хотите поделиться, пожалуйста, свяжитесь с автором по адресу tirthajyoti[AT]gmail.com . Также вы можете проверить авторские репозитории GitHub на наличие других забавных фрагментов кода в Python, R или MATLAB и ресурсах машинного обучения. Если вы, как и я, увлечены машинным обучением/наукой о данных, пожалуйста, не стесняйтесь добавить меня в LinkedIn или следовать за мной в Twitter.