Получить длины векторов без загрузки нескольких файлов .npy - PullRequest
0 голосов
/ 19 октября 2018

У меня есть около 2000 файлов .npy, каждый из которых представляет одномерный вектор чисел с плавающей точкой от 100 000 до 1 000 000 записей (оба эти числа в будущем существенно возрастут).Для каждого файла мне нужна длина вектора, который он содержит.Следующая опция возможна, но занимает много времени:

lengths = [numpy.shape(numpy.load(whatever))[0] for whatever in os.listdir(some_dir)]

Вопрос: Какой самый эффективный / быстрый способ вывести этот список векторных длин?Конечно, я должен быть в состоянии работать непосредственно с размерами файлов, но каков наилучший способ сделать это?

Ответы [ 2 ]

0 голосов
/ 19 октября 2018

Использование файлов меммапа значительно ускорит это.Путем сопоставления файла numpy загружает только заголовок, чтобы получить формы массива и тип данных, тогда как фактические данные массива остаются на диске до тех пор, пока они не понадобятся.

import numpy as np 
# Load files using memmap
data = [np.load(f, mmap_mode='r')) for f in os.listdir(some_dir)]
# Checking your assumptions never hurts
assert (d.ndim == 1 for d in data).all()  

lengths = [d.shape[0] for d in data]

edit Причина, по которой вам нужно загрузитьзаголовки файлов вместо непосредственного использования размера файлов заключаются в том, что заголовок для файлов npy не обязательно имеет фиксированную длину.Хотя для одномерного массива без полей или имен полей он, вероятно, не изменится (см. https://www.numpy.org/devdocs/reference/generated/numpy.lib.format.html).

0 голосов
/ 19 октября 2018

Вы, вероятно, можете попробовать это

import os

fileinfo = os.stats('1darray.npy')

длина массива

a = os.stat('1darray.npy')
int((a.st_size - 128)/itemsize) 

128 - это файл npy дополнительного размера, который сохраняется при сохранении в каталоге в ОС,фактический размер любого байтового массива в байтах можно найти в виде array.nbytes.Так a.st_size - 128 = array.nbytes и array.bytes/array.itemsize = array.size = array lenght

Где itemsize = 2, если массив имеет тип float 16 бит, 4, если тип является плавающим 32 бит, и 8, если массив, если тип float 64 bit

Вот демонстрационная версия

import numpy as np
import os
array = np.arange(12, dtype=np.float64)
print(a.itemsize) # >> gives 8 for float 64 bit
np.save('1darray.npy', array)
a = os.stat('1darray.npy')
length = int((a.st_size - 128)/8) # >> gives 12 which is equal to array.size

, поэтому вы должны знать, что такое dtype сохраненных numpy npy файлов

Поэтому для вашего случаяВы можете сделать это

lengths = [(os.stat(whatever).st_size - 128)/8 for whatever in os.listdir(some_dir)] 

, предполагая, что dtypes массивов npy равен float64

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...