Автор оригинала: 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.